Overview
| Comment: | add memory pool impl, handle various little details, add beginnings of mimelib |
|---|---|
| Downloads: | Tarball | ZIP archive | SQL archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
8d35307a7f76cc6624c69b3f11b1203c |
| User & Date: | lexi on 2021-01-10 03:54:46 |
| Other Links: | manifest | tags |
Context
|
2021-01-10
| ||
| 08:19 | begin replacing inefficient memory management with a pool-based solution; fix memory leaks check-in: 7c8769bf96 user: lexi tags: trunk | |
| 03:54 | add memory pool impl, handle various little details, add beginnings of mimelib check-in: 8d35307a7f user: lexi tags: trunk | |
|
2021-01-09
| ||
| 07:15 | user mgmt and rt improvements check-in: 05af79b909 user: lexi tags: trunk | |
Changes
Modified backend/pgsql.t from [175b022aff] to [794844a9c8].
1 1 -- vim: ft=terra 2 2 local pstring = lib.mem.ptr(int8) 3 3 local binblob = lib.mem.ptr(uint8) 4 4 local queries = { 5 + server_setup_self = { 6 + params = {rawstring,binblob,int64}, cmd = true, sql = [[ 7 + insert into parsav_servers (id, domain, key, parsav, knownsince) 8 + values (0, $1::text, $2::bytea, true, $3::bigint) 9 + ]]; 10 + }; 11 + 12 + server_fetch_sid = { 13 + params = {uint64}, sql = [[ 14 + select domain, key, knownsince, parsav from parsav_servers 15 + where id = $1::bigint 16 + ]]; 17 + }; 18 + 5 19 conf_get = { 6 20 params = {rawstring}, sql = [[ 7 21 select value from parsav_config 8 22 where key = $1::text limit 1 9 23 ]]; 10 24 }; 11 25 ................................................................................ 1146 1160 tx_enter = txdo, tx_complete = txdone; 1147 1161 1148 1162 conprep = [terra(src: &lib.store.source, mode: lib.store.prepmode.t): {} 1149 1163 var [con] = [&lib.pq.PGconn](src.handle) 1150 1164 if mode == lib.store.prepmode.full then [prep] 1151 1165 elseif mode == lib.store.prepmode.conf or 1152 1166 mode == lib.store.prepmode.admin then 1167 + queries.server_setup_self.prep(con) 1153 1168 queries.conf_get.prep(con) 1154 1169 queries.conf_set.prep(con) 1155 1170 queries.conf_reset.prep(con) 1156 1171 if mode == lib.store.prepmode.admin then 1172 + queries.server_fetch_sid.prep(con) 1173 + queries.actor_fetch_uid.prep(con) 1174 + queries.actor_fetch_xid.prep(con) 1175 + queries.actor_enum.prep(con) 1176 + queries.actor_enum_local.prep(con) 1177 + queries.actor_stats.prep(con) 1178 + queries.actor_powers_fetch.prep(con) 1179 + queries.actor_save.prep(con) 1180 + queries.actor_create.prep(con) 1181 + queries.actor_purge_uid.prep(con) 1157 1182 end 1158 1183 else lib.bail('unsupported connection preparation mode') end 1159 1184 end]; 1185 + 1186 + server_setup_self = [terra( 1187 + src: &lib.store.source, 1188 + domain: rawstring, 1189 + key: binblob 1190 + ): {} 1191 + queries.server_setup_self.exec(src,domain,key,lib.osclock.time(nil)) 1192 + end]; 1160 1193 1161 1194 dbsetup = [terra(src: &lib.store.source): bool 1162 1195 var res = lib.pq.PQexec([&lib.pq.PGconn](src.handle), schema) 1163 1196 if lib.pq.PQresultStatus(res) == lib.pq.PGRES_COMMAND_OK then 1164 1197 lib.report('successfully instantiated schema in database') 1165 1198 return true 1166 1199 else
Modified backend/schema/pgsql.sql from [29d1b18fbc] to [bc736c4c1d].
1 1 create table parsav_config ( 2 2 key text primary key, 3 3 value text 4 4 ); 5 +comment on table parsav_config is 6 +'server-wide configuration variables. highly sensitive!'; 5 7 6 8 insert into parsav_config (key,value) values ('schema-version','1'), 7 9 ('credential-store','managed'); 8 10 -- ('bind',:'bind'), 9 11 -- ('domain',:'domain'), 10 12 -- ('instance-name',:'inst'), 11 13 -- ('policy-security',:'secmode'), ................................................................................ 17 19 create table parsav_servers ( 18 20 id bigint primary key default (1+random()*(2^63-1))::bigint, 19 21 domain text not null unique, 20 22 key bytea, 21 23 knownsince bigint, 22 24 parsav boolean -- whether to use parsav protocol extensions 23 25 ); 26 +comment on table parsav_servers is 27 +'all servers known to the parsav instance. the local server (including its private key) is stored in row (id = 0)'; 24 28 25 29 create table parsav_actors ( 26 30 id bigint primary key default (1+random()*(2^63-1))::bigint, 27 31 nym text, 28 32 handle text not null, -- nym [@handle@origin] 29 33 origin bigint references parsav_servers(id) 30 34 on delete cascade, -- null origin = local actor ................................................................................ 37 41 invites integer not null default 0, 38 42 key bytea, -- private if localactor; public if remote 39 43 epithet text, 40 44 authtime bigint not null, -- cookies earlier than this timepoint will not be accepted 41 45 42 46 unique (handle,origin) 43 47 ); 48 +comment on table parsav_actors is 49 +'all users known to the instance across the fediverse; local users satisfy constraint (origin = 0)'; 44 50 45 51 create table parsav_rights ( 46 52 key text, 47 53 actor bigint references parsav_actors(id) 48 54 on delete cascade, 49 55 allow boolean not null, 50 56 scope bigint, -- for future expansion 51 57 52 58 primary key (key,actor) 53 59 ); 54 60 create index on parsav_rights (actor); 61 +comment on table parsav_rights is 62 +'a backward-compatible list of every non-default privilege or deprivilege granted to a local user'; 55 63 56 64 create table parsav_posts ( 57 65 id bigint primary key default (1+random()*(2^63-1))::bigint, 58 66 author bigint references parsav_actors(id) on delete cascade, 59 67 subject text, 60 68 acl text not null default 'all', -- just store the script raw 🤷 61 69 body text, ................................................................................ 81 89 on delete cascade, -- e.g. follower 82 90 relatee bigint references parsav_actors(id) 83 91 on delete cascade, -- e.g. followed 84 92 kind smallint, -- e.g. follow, block, mute 85 93 86 94 primary key (relator, relatee, kind) 87 95 ); 96 +comment on table parsav_rels is 97 +'all relationships, positive and negative, between local users and other users; kind is a version-specific integer mapping to a type-of-relationship enum in store.t'; 88 98 89 99 create table parsav_acts ( 90 100 id bigint primary key default (1+random()*(2^63-1))::bigint, 91 101 kind text not null, -- like, rt, react, so on 92 102 time bigint not null, 93 103 actor bigint references parsav_actors(id) on delete cascade, 94 104 subject bigint, -- may be post or act, depending on kind 95 - body text -- emoji, if react 105 + body text -- emoji, if react; complaint, if report 96 106 ); 97 107 create index on parsav_acts (subject); 98 108 create index on parsav_acts (actor); 99 109 create index on parsav_acts (time); 110 +comment on table parsav_acts is 111 +'every simple action taken on a tweet by an actor, including likes, rts, reacts, and reports'; 100 112 101 113 create table parsav_log ( 102 114 -- accesses are tracked for security & sending delete acts 103 115 id bigint primary key default (1+random()*(2^63-1))::bigint, 104 116 time bigint not null, 105 117 actor bigint references parsav_actors(id) 106 118 on delete cascade, 107 119 post bigint not null 108 120 ); 121 +comment on table parsav_log is 122 +'a log of accesses from foreign servers, tracking which will be sent update & delete events for each post'; 109 123 110 124 create table parsav_artifacts ( 111 125 id bigint primary key default (1+random()*(2^63-1))::bigint, 112 126 birth bigint not null, 113 127 content bytea, -- if null, this is a "ban record" preventing content matching the hash from being re-uploaded 114 128 hash bytea unique not null, -- sha256 hash of content 115 129 -- it would be cool to use a computed column for this, but i don't want 116 130 -- to lock people into PG12 or drag in the pgcrypto extension just for this 117 - mime text -- null if unknown, will be reported as x-octet-stream 131 + mime text -- null if unknown, will be reported as octet-stream 118 132 ); 119 133 create index on parsav_artifacts (mime); 134 +comment on table parsav_artifacts is 135 +'deduplicated media files uploaded by users'; 120 136 121 137 create table parsav_artifact_claims ( 122 138 birth bigint not null, 123 139 uid bigint references parsav_actors(id) on delete cascade, 124 140 rid bigint references parsav_artifacts(id) on delete cascade, 125 141 description text, 126 142 folder text, 127 143 128 144 unique (uid,rid) 129 145 ); 130 146 create index on parsav_artifact_claims (uid); 131 147 create index on parsav_artifact_claims (uid,folder); 148 +comment on table parsav_artifact_claims is 149 +'a list of users who have an ownership interest in each artifact (effectively an index of GC roots)'; 132 150 133 151 create table parsav_circles ( 134 152 id bigint primary key default (1+random()*(2^63-1))::bigint, 135 153 owner bigint not null references parsav_actors(id) on delete cascade, 136 154 name text not null, 137 155 members bigint[] not null default array[]::bigint[], 138 156 ................................................................................ 143 161 create table parsav_rooms ( 144 162 id bigint primary key default (1+random()*(2^63-1))::bigint, 145 163 origin bigint references parsav_servers(id) on delete cascade, 146 164 name text not null, 147 165 description text not null, 148 166 policy smallint not null 149 167 ); 168 +comment on table parsav_rooms is 169 +'an index of user-created chatrooms'; 150 170 151 171 create table parsav_room_members ( 152 172 room bigint not null references parsav_rooms(id) on delete cascade, 153 173 member bigint not null references parsav_actors(id) on delete cascade, 154 174 rank smallint not null default 0, 155 175 admin boolean not null default false, -- non-admins with rank can only moderate + invite 156 176 title text, -- admin-granted title like reddit flair ................................................................................ 165 185 -- ID becomes the user ID. privileges granted on the invite ID during the invite 166 186 -- process are thus inherited by the user 167 187 issuer bigint references parsav_actors(id) on delete set null, 168 188 handle text, -- admin can lock invite to specific handle 169 189 rank smallint not null default 0, 170 190 quota integer not null default 1000 171 191 ); 192 +comment on table parsav_invites is 193 +'all active invitations and the level of authority they grant if accepted'; 172 194 173 195 create table parsav_sanctions ( 174 196 id bigint primary key default (1+random()*(2^63-1))::bigint, 175 197 issuer bigint references parsav_actors(id) on delete set null, 176 198 scope bigint, -- can be null or room for local actions 177 199 nature smallint not null, -- silence, suspend, disemvowel, censor, noreply, etc 178 200 victim bigint not null, -- can be user, room, or post ................................................................................ 180 202 review bigint, -- brings up for review at given time if set 181 203 reason text, -- visible to victim if set 182 204 context text, -- admin-only note 183 205 appeal text -- null if no appeal lodged 184 206 ); 185 207 create index on parsav_sanctions (victim,scope); 186 208 create index on parsav_sanctions (issuer); 209 +comment on table parsav_sanctions is 210 +'administrative actions taken against particular users, posts, rooms, or other entities'; 187 211 188 212 create table parsav_actor_conf_strs ( 189 213 uid bigint not null references parsav_actors(id) on delete cascade, 190 214 key text not null, value text not null, unique (uid,key) 191 215 ); 192 216 create table parsav_actor_conf_ints ( 193 217 uid bigint not null references parsav_actors(id) on delete cascade, 194 218 key text not null, value bigint not null, unique (uid,key) 195 219 ); 220 +comment on table parsav_actor_conf_strs is 'per-user configuration settings (string properties)'; 221 +comment on table parsav_actor_conf_ints is 'per-user configuration settings (integer and enumeration properties)'; 196 222 197 223 -- create a temporary managed auth table; we can delete this later 198 224 -- if it ends up being replaced with a view 199 225 %include pgsql-auth.sql%
Modified mem.t from [a0c3213659] to [de24aef2de].
173 173 v.metamethods.__apply = terra(self: &v, idx: intptr): &ty -- no index?? 174 174 if self.sz > idx then 175 175 return self.storage.ptr + idx 176 176 else lib.bail('vector overrun!') end 177 177 end 178 178 return v 179 179 end) 180 + 181 +struct m.pool { 182 + -- implements growable memory pools. EVERY THREAD MUST HAVE ITS OWN 183 + storage: &opaque 184 + cursor: &opaque 185 + sz: intptr 186 +} 187 + 188 +terra m.pool:cue(sz: intptr) 189 + if self.storage == nil then 190 + self.storage = m.heapa_raw(sz) 191 + self.cursor = self.storage 192 + self.sz = sz 193 + else 194 + if self.sz >= sz then return self end 195 + var ofs = [&uint8](self.cursor) - [&uint8](self.storage) 196 + self.storage = m.heapr_raw(self.storage, sz) 197 + self.cursor = [&opaque]([&uint8](self.storage) + ofs) 198 + self.sz = sz 199 + end 200 + return self 201 +end 202 + 203 +terra m.pool:init(sz: intptr) 204 + self.storage = nil 205 + self:cue(sz) 206 + return self 207 +end 208 + 209 +terra m.pool:free() 210 + m.heapf(self.storage) 211 + self.storage = nil 212 + self.cursor = nil 213 + self.sz = 0 214 +end 215 + 216 +terra m.pool:clear() 217 + self.cursor = self.storage 218 + return self 219 +end 220 + 221 +terra m.pool:alloc_bytes(sz: intptr): &opaque 222 + var space = self.sz - ([&uint8](self.cursor) - [&uint8](self.storage)) 223 + if space < sz then self:cue(space + sz + 256) end 224 + var ptr = self.cursor 225 + self.cursor = [&opaque]([&uint8](self.cursor) + sz) 226 + return ptr 227 +end 228 + 229 +m.pool.methods.alloc = macro(function(self,ty,sz) 230 + return `[ty](self:alloc_bytes(sizeof(ty) * sz)) 231 +end) 232 + 233 +terra m.pool:frame() -- stack-style linear mgmt 234 + return self.cursor 235 +end 236 + 237 +terra m.pool:reset(frame: &opaque) 238 + self.cursor = frame 239 + return self 240 +end 241 + 180 242 181 243 return m
Modified mgtool.t from [b1a646e421] to [b40be7a821].
287 287 288 288 srv:setup(cnf) 289 289 if lib.str.cmp(dbmode.arglist(0),'init') == 0 and dbmode.arglist.ct == 2 then 290 290 lib.report('initializing new database structure for domain ', dbmode.arglist(1)) 291 291 dlg:tx_enter() 292 292 if dlg:dbsetup() then 293 293 srv:conprep(lib.store.prepmode.conf) 294 + 295 + do var newkp = lib.crypt.genkp() 296 + -- generate server privkey 297 + var kbuf: uint8[lib.crypt.const.maxdersz] 298 + var privsz = lib.crypt.der(false,&newkp, kbuf) 299 + dlg:server_setup_self(dbmode.arglist(1), [lib.mem.ptr(uint8)] { 300 + ptr = &kbuf[0], ct = privsz 301 + }) 302 + end 303 + 294 304 dlg:conf_set('instance-name', dbmode.arglist(1)) 295 305 dlg:conf_set('domain', dbmode.arglist(1)) 296 306 do var sec: int8[65] gensec(&sec[0]) 297 - dlg:conf_set('server-secret', &sec[0]) 298 307 dlg:conf_set('server-secret', &sec[0]) 299 308 end 300 309 lib.report('database setup complete; use mkroot to create an administrative user') 301 310 else lib.bail('initialization process interrupted') end 302 311 dlg:tx_complete() 303 312 elseif lib.str.cmp(dbmode.arglist(0),'obliterate') == 0 then 304 313 var cfmstr: int8[64] gen_cfstr(&cfmstr[0],0)
Added mime.t version [2e40a434e4].
1 +local knowntypes = { 2 + ['text/csrc'] = { 3 + ext = 'c', lang = 'c'; 4 + }; 5 + ['text/html'] = { 6 + ext = 'html', lang = 'html'; 7 + unsafe = true; 8 + }; 9 + ['text/markdown'] = { 10 + formatter = 'smackdown'; 11 + ext = 'md', doc = true; 12 + }; 13 +}
Modified parsav.md from [52b33381db] to [1e18c01a8c].
1 1 # parsav 2 2 3 3 **parsav** is a lightweight social media server written in [terra](https://terralang.org), intended to integrate to some degree with the fediverse. it is named for the [Ranuir](http://Êž.cc/fic/spirals/ranuir) words *par* "speech, communication" and *sav* "unity, togetherness, solidarity". 4 4 5 5 ## backends 6 6 parsav is designed to be storage-agnostic, and can draw data from multiple backends at a time. backends can be enabled or disabled at compile time to avoid unnecessary dependencies. 7 7 8 -* postgresql 8 +* postgresql (backend `pgsql`) 9 9 10 10 ## dependencies 11 11 12 12 * runtime 13 13 * mongoose 14 14 * json-c 15 15 * mbedtls ................................................................................ 21 21 22 22 additional preconfigure dependencies are necessary if you are building directly from trunk, rather than from a release tarball that includes certain build artifacts which need to be embedded in the binary: 23 23 24 24 * inkscape, for rendering out some of the UI graphics that can't be represented with standard svg 25 25 * cwebp (libwebp package), for transforming inkscape PNGs to webp 26 26 * sassc, for compiling the SCSS stylesheet into its final CSS 27 27 28 -all builds require terra, which, unfortunately, requires installing an older version of llvm, v9 at the latest (which i develop parsav under). with any luck, your distro will be clever enough to package terra and its dependencies properly (it's trivial on nix, tho you'll need to tweak the terra expression to select a more recent llvm package); Arch Linux is one of those distros which is not so clever, and whose (AUR) terra package is totally broken. due to these unfortunate circumstances, terra is distributed not just in source form, but also in the the form of LLVM IR. 28 +all builds require terra, which, unfortunately, requires installing an older version of llvm, v9 at the latest (which i develop parsav under). with any luck, your distro will be clever enough to package terra and its dependencies properly (it's trivial on nix, tho you'll need to tweak the terra expression to select a more recent llvm package if you want v9; this isn't necessary to successfully build parsav however); Arch Linux is one of those distros which is not so clever, and whose (AUR) terra package is totally broken. due to these unfortunate circumstances, terra is distributed not just in source form, but also in the the form of LLVM IR and x86-64 assembly + object code. 29 29 30 -i've noticed that terra (at least with llvm9) seems to get a bit cantankerous and trigger llvm to fail with bizarre errors when you try to cross-compile parsav from x86-64 to any other platform, even x86-32. i don't know if this problem exists on other architectures or in what form. as a workaround, i've tried generating LLVM IR (ostensibly for x86-64, though this is in reality an architecture-independent language), and then compiling that down to an object file with llc. it doesn't work. the generated binaries seem to run but they crash with bizarre errors and are impossible to debug, as llc refuses to include debug symbols. for these reasons, parsav will (almost certainly) not run on any architecture besides x86-64, at least until terra and/or llvm are fixed. 30 +i've noticed that terra (at least with llvm 6 and 9) seems to get a bit cantankerous and trigger llvm to fail with bizarre errors when you try to cross-compile parsav from x86-64 to any other platform, even x86-32. i don't know if this problem exists on other architectures or in what form. as a workaround, i've tried generating LLVM IR (putatively for x86-64, though this is an ostensibly architecture-independent language), and then compiling that down to an object file with llc. it doesn't work. the generated binaries seem to run but they crash with bizarre errors and are impossible to debug, as llc refuses to include debug symbols. for these reasons, parsav will (almost certainly) not run on any architecture besides x86-64, at least until terra and/or llvm are fixed. there is a very small possibility however that compiling natively on an ARM or x86-32 host might succeed. if you can pull it off, please let me know and i'll update the docs. 31 31 32 32 also note that, while parsav has a flag to build with ASAN, ASAN has proven unusable for most purposes as it routinely reports false positive buffer-heap-overflows. if you figure out how to defuckulate this, i will be overjoyed. 33 33 34 34 ## building 35 35 36 36 first, either install any missing dependencies as shared libraries, or build them as static libraries with the command `make dep.$LIBRARY`. as a shortcut, `make dep` will build all dependencies as static libraries. note that if the build system finds a static version of a library in the `lib/` folder, it will use that instead of any system library. note that these commands require GNU make (it may be installed as `gmake` on your system), although this is a fairly soft dependency -- if you really need to build it on BSD make, you can probably translate it with a minute or so of work; you'll just have to do some of the various gmake functions' work manually. this may be worthwhile if you're packaging for a BSD. 37 37 38 38 postgresql-libs must be installed systemwide, as `parsav` does not currently provide for statically compiling and linking it 39 39 40 40 if you use nixos and wish to build the pdf documentation, you're going to have to do a bit of extra work (but you're used to that, aren't you). for some incomprehensible reason, the groff package on nix is split up, seemingly randomly, with many crucial output devices relegated to the "perl" output of the package, which is not installed by default (and `nix-env -iA nixos.groff.perl` doesn't work either; i don't know why either). you'll have to instantiate and install the outputs directly by path, e.g. `nix-env -i /nix/store/*groff*/` to get everything you need into your profile. alas, the battle is not over: you also need to change the environment variables `GROFF_FONT_PATH` and `GROFF_TMAC_PATH` to point at the `font` and `tmac` subdirs of `~/.nix-profile/share/groff/$groff_version/`. once this is done, invoking `groff -Tpdf` will work as expected. 41 41 42 -## configuring 42 +unfortunately, the produced daemon binary is rather large, weighing in around 600K at the time of writing. you can reduce this significantly however by `strip`ping the binary, and reduce it further by compiling without debug functionality turned on (i.e. no debug symbols and no debug log level, both of which insert a large number of strings into the resulting object code). 43 + 44 +## configuration 43 45 44 46 the `parsav` configuration is comprised of two components: the backends list and the config store. the backends list is a simple text file that tells `parsav` which data sources to draw from. the config store is a key-value store which contains the rest of the server's configuration, and is loaded from the backends. the configuration store can be spread across the backends; backends will be checked for configuration keys according to the order in which they are listed. changes to the configuration store affect parsav in real time; you only need to restart the server if you make a change to the backend list. 45 47 46 48 you can directly modify the store from the command line with the `parsav conf` command; see `parsav conf -h` for more information. 47 49 48 50 by default, parsav looks for a file called `backend.conf` in the current directory when it is launched. you can override this default with the `parsav_backend_file` environment or with the `-b`/`--backend-file` flag. `backend.conf` lists one backend per line, in the form `id type confstring`. for instance, if you had two postgresql databases, you might write a backend file like 49 51 50 52 master pgsql host=localhost dbname=parsav 51 53 tweets pgsql host=420.69.dread.cloud dbname=content 52 54 53 -the form the configuration string takes depends on the specific backend. 55 +the form the configuration string takes depends on the specific backend. for postgres, it's just the standard postgres connection string, and supports all the usual properties, as it's passed directly to the client library unmodified. 54 56 55 57 once you've set up a backend and confirmed parsav can connect succesfully to it, you can initialize the database with the command `parsav db init <domain>`, where `<domain>` is the name of the domain name you will be hosting `parsav` from. this will install all necessary structures and functions in the target and create all necessary files. it will not, however, create any users. you can create an initial administrative user with the `parsav mkroot <handle>` command, where `<handle>` is the handle you want to use on the server. this will also assign a temporary password for the user if possible. you should now be able to log in and administer the server. 56 58 57 59 if something goes awry with your administrative account, don't fret! you can get your powers themselves back with the command `parsav user <handle> grant all`, and if you're having difficulties logging in, the command `parsav user <handle> auth pw reset` will give you a fresh password. if all else fails, you can always run `mkroot` again to create a new root account, and try to repair the damage from there. 58 60 59 61 by default, parsav binds to [::1]:10917. if you want to change this (to run it on a different port, or make it directly accessible to other servers on the network), you can use the command `parsav conf set bind <address>`, where `address` is a binding specification like `0.0.0.0:80`. it is recommended, however, that `parsavd` be kept accessible only from localhost, and that connections be forwarded to it from nginx, haproxy, or a similar reverse proxy. (this can also be changed with the online configuration UI) 60 62 ................................................................................ 127 129 128 130 * plain text/filesystem storage 129 131 * lmdb 130 132 * sqlite3 131 133 * generic odbc 132 134 * lua 133 135 * ldap for auth (and maybe actors?) 134 -* cdb (for static content, maybe?) 136 +* cdb (for static content, maybe? does this make sense?) 135 137 * mariadb/mysql 136 138 * the various nosql horrors, e.g. redis, mongo, and so on 137 139 138 140 parsav urgently needs an internationalization framework as well. right now everything is just hardcoded in english. yuck. 141 + 142 +parsav could be significantly improved by adjusting its memory management strategy. instead of allocating everything with lib.mem.heapa (which currently maps to malloc on all platforms), we should allocate a static buffer for the server overlord object which can simply be cleared and re-used for each http request, and enlarged with `realloc` when necessary. the entire region could be `mlock`ed for better performance, and it would no longer be necessary to track and free memory, as the entire buffer would simply be discarded after use (similar to PHP's original memory management strategy). this would remove possibly the largest source of latency in the codebase, as `parsav` is regrettably quite heavy on malloc, performing numerous allocations for each page rendered.
Modified render/nav.t from [50b4e7c2b2] to [0fd87c81ae].
3 3 render_nav(co: &lib.srv.convo) 4 4 var t: lib.str.acc t:init(64) 5 5 if co.who ~= nil or co.srv.cfg.pol_sec == lib.srv.secmode.public then 6 6 t:lpush(' <a accesskey="t" href="/">timeline</a>') 7 7 end 8 8 if co.who ~= nil then 9 9 t:lpush(' <a accesskey="c" href="/compose">compose</a> <a accesskey="p" href="/'):push(co.who.xid,0) 10 - t:lpush('">profile</a> <a accesskey="m" href="/media">media</a> <a accesskey="o" href="/conf">configure</a> <a accesskey="d" href="/doc">docs</a> <a accesskey="g" href="/logout">log out</a> <a class="bell" accesskey="x" href="/notices">notices</a>') 10 + t:lpush('">profile</a> <a accesskey="m" href="/media">media</a> <a accesskey="o" href="/conf">configure</a> <a accesskey="d" href="/doc">docs</a> <div class="ident">@') 11 + t:push(co.who.handle,0) 12 + t:lpush('</div> <a accesskey="g" href="/logout">log out</a> <a class="bell" accesskey="x" href="/notices">notices</a>') 11 13 else 12 14 t:lpush(' <a accesskey="d" href="/doc">docs</a> <a accesskey="g" href="/login">log in</a>') 13 15 end 14 16 return t:finalize() 15 17 end 16 18 return render_nav
Modified route.t from [a8702e1420] to [2b1fe64d41].
360 360 end)()] 361 361 privs:dump() 362 362 if privs:sz() > 0 then 363 363 lib.dbg('installing credential restrictions') 364 364 lib.io.fmt('on priv %llu\n',aid) 365 365 co.srv:auth_privs_set(aid, privs) 366 366 end 367 + 368 + lib.dbg('setting netmask restrictions') 369 + var nm = co:pgetv('netmask') 367 370 end 368 371 co:reroute('?') 369 372 return 370 373 end 371 374 co:complain(400,'bad request','the operation you have requested is not meaningful in this context') 372 375 end 373 376
Modified static/style.scss from [f9852f8724] to [ba9256aed1].
210 210 } 211 211 nav { 212 212 all: unset; 213 213 display: flex; 214 214 justify-content: flex-end; 215 215 align-items: center; 216 216 grid-column: 2/3; grid-row: 1/2; 217 + .ident { 218 + color: tone(-20%); 219 + margin-left: 0.2em; 220 + border-left: 1px solid tone(-40%); 221 + padding-left: 0.5em; 222 + } 217 223 > a[href] { 218 224 display: block; 219 225 padding: 0.25in 0.10in; 220 226 //padding: calc((25% - 1em)/2) 0.15in; 221 227 &, &::after { transition: 0.3s; } 222 228 text-shadow: 1px 1px 1px black; 223 229 &:hover{ ................................................................................ 516 522 margin: unset; 517 523 grid-template-columns: 1in 1fr max-content max-content; 518 524 grid-template-rows: min-content max-content; 519 525 margin-bottom: 0.1in; 520 526 transition: 0.2s ease-out; 521 527 >.avatar { 522 528 grid-column: 1/2; grid-row: 1/2; 523 - img { display: block; width: 1in; height: 1in; margin:0; } 524 529 background: linear-gradient(to bottom, tone(-53%), tone(-57%)); 530 + img { 531 + display: block; width: 1in; height: 1in; margin:0; 532 + border-right: 1px solid tone(-65%); 533 + } 525 534 } 526 535 >a[href].username { 527 536 display: block; 528 537 grid-column: 1/3; 529 538 grid-row: 2/3; 530 539 text-align: left; 531 540 text-decoration: none;
Modified store.t from [0ebd27b207] to [adf1545306].
353 353 354 354 tx_enter: &m.source -> bool 355 355 tx_complete: &m.source -> bool 356 356 -- these two functions are special, in that they should be called 357 357 -- directly on a specific backend, rather than passed down to the 358 358 -- backends by the server; that is pathological behavior that will 359 359 -- not have the desired effect 360 + 361 + server_setup_self: {&m.source, rawstring, lib.mem.ptr(uint8)} -> {} 360 362 361 363 conf_get: {&m.source, rawstring} -> lib.mem.ptr(int8) 362 364 conf_set: {&m.source, rawstring, rawstring} -> {} 363 365 conf_reset: {&m.source, rawstring} -> {} 364 366 365 367 actor_create: {&m.source, &m.actor} -> uint64 366 368 actor_save: {&m.source, &m.actor} -> {}