aboutsummaryrefslogtreecommitdiffstats
path: root/prototypes/connections/Makefile
Commit message (Collapse)AuthorAgeFilesLines
* Lay Pure out as a core with the parts selected around iteunhhu2026-09-271-48/+32
| | | | | | | | | | | | | | | | | | | | | The app model, the tree store and the HTTP host lived in prototypes/connections among the earlier document runtime, the store was known only by its format's name, and Vega compiled six Pure sources by path. Now, as the README's principle has it: core/ runtime, flow and the app model (module*.c), with what the core asks of storage (state.h, store.h) store/ the tree store (PURETRE3, PUREREC1) serve/ pure-serve: HTTP host, outbound delivery, JSON in place cli/ pure-run, pure-edit-module A top-level make builds libpure.a (app model and store, for hosts to link) and the hosts; make check runs the store's and the app model's tests. The earlier runtime still builds from prototypes/connections against core/ and store/ (check, check-tree and check-core pass). Design 009 records the rule: parts by role behind libraries; git repositories split by coupling, so the store stays here while its contract moves with the core, and Vega stays apart.
* Read JSON messages in message-json.c, for requests and answers alikeeunhhu2026-09-271-2/+2
| | | | | | | | | The in-place JSON reader of pure-serve's request bodies moves into its own file with a small interface (pure_json_message, pure_json_fixed, pure_json_space), so the delivery client can read an API's answers with it. It gains a lenient mode for answers: a member that names no field is skipped, value and all. Requests read as before.
* Deliver to https receivers, verifying their certificates (083)eunhhu2026-09-271-1/+1
| | | | | | | | | | A wire to an https:// URL speaks TLS 1.2 or later through OpenSSL: the receiver's certificate must chain to the system's CAs (or to the file --send-ca names) and name its host (SNI and SSL_set1_host, or the IP address). An untrusted receiver gets nothing: the send stays in the outbox, the wire logs it and tries again every 10 s. pure-serve now links libssl and libcrypto.
* Deliver an app's saved sends over HTTP, in order and in batches (083)eunhhu2026-09-271-2/+2
| | | | | | | | | | | | | | | | | | | | pure-serve --send OUTPUT=http://host:port/path wires an output: after every save the owner queues the new sends as JSON (fields and groups) and a thread per output posts them in order with X-Pure-Source, X-Pure-Sequence and Idempotency-Key. A 2xx, or a Pure receiver's refusal, delivers; the owner then trims. 408, 429, 5xx and no answer are sent again after a pause growing to 10 s, other answers every 10 s: nothing is dropped. A Pure receiver applies a delivered message with pure_app_deliver (now taking placed fields) and advertises X-Pure-Batch: 256; the sender then posts up to that many numbers in a row as one JSON array (X-Pure-Count), applied in order in one burst with one save. Delivery kept up with orders once batched (391 deliveries/s one at a time; a backlog of 20,000 went at 60k/s). With four clients ordering, killing the receiver and then the sender (-9) left the receiver's count and total equal to what the sender saved, five times and under ASan.
* Snapshot an app's saved states for readers on other threadseunhhu2026-09-261-1/+1
| | | | | | | | | | | | | | | | | | | | | | Right after a save, pure_app_snapshot makes a read-only snapshot of the saved states: numbers are copied, text states are frozen drafts that share the store mapping (pure_draft_freeze, no copy), and lists are copies of their item pointers that share the items. An unchanged list shares the last snapshot's copy. pure_app_read binds a reader app on another thread to a snapshot so the existing view functions read it. A shared item never changes again: a list stamps each item with its share count, copies a shared item it changes, and retires shared items it lets go instead of freeing them. Snapshots form a chain that goes oldest first, and items retired while a snapshot was the newest go with it. References are atomic and may be released on any thread. test-module checks that each snapshot equals the app, that kept snapshots stay as made through changes, removals, a module switch, the app stopping and the store closing, that a failed save's snapshot equals the one before, and that two threads read the newest snapshots while the app goes on (also under ASan, UBSan and LeakSanitizer).
* Rebuild module hosts when the executor or store changeseunhhu2026-09-261-2/+3
| | | | | | | | MODULE and MODULE_HEADERS were defined below the pure-serve rule, and a rule's prerequisites expand when make reads it, so pure-serve depended on neither: changing the store or the executor left a stale server behind. Define them before any rule names them.
* Serve modules over persistent connectionseunhhu2026-09-261-4/+4
| | | | | | | | | | | | | | | | pure-serve replaces the module mode of server.c, which goes back to what it was. It keeps the document contract, the runtime core (a work slot per connection, the payload budget, core-owned ingress, borrowed PUT replies) and the group commits, and adds what server.c lacked: HTTP/1.1 persistent connections with in-order pipelining, an edge-triggered epoll owner thread, up to 1,024 connections allocated as they arrive and reused, one writev per answer, and documents opened through a store handle. On the Pi 5 with one thread it serves 106k small keep-alive reads per second (axum on three cores: 126k) at the same p99, 1,741 1 MiB reads (axum: 1,370), and 1,126 durable writes from 64 connections (crash-safe axum: 372), in 7.3 MiB against axum's 17-20 MiB. Note 075 has the table.
* Serve modules through the runtime core with group commitseunhhu2026-09-261-1/+5
| | | | | | | | | | | | | | | | pure-connections-module offers the document server's HTTP contract with an aup module: GET is its show message and PUT its edit message. Requests go through the runtime core as before (work slots, payload budget, ingress, replies borrowed from the request), and effects are taken on the owner thread with the core's asynchronous interface. Each poll round is one burst: every ready request is applied to the app with deferred saving, one save stores them, and only then are the tickets completed and answered. A failed save fails the whole burst, reads too. A key seen again ends the burst first, and the module server accepts every waiting connection at once so concurrent requests share a burst. On the Pi's SD card eight clients' 240 edits take 0.59 s instead of 2.14 s.
* Keep app states in the tree storeeunhhu2026-09-251-6/+6
| | | | | | | | | | | | | | | | | | | | | | | When the data host keeps states (PureData.state and .save, implemented by pure_tree_data), every state of an app lives in the store: a text state's draft is its stored value, a list mirrors each change into a stored draft (record header, then items), and numbers, cursors and indices are stored together by name. An app starts from what is stored, moves list fields by name when a record changed, resets cursors and indices that no longer fit, and refuses damaged stored values. Each key, text and message event publishes the states it changed together with the message's document in one store commit, or fails and leaves memory and store as they were. Frame changes go with the next event or pure_app_save. pure-run takes --store PATH. Tests run the same random events on an app in memory and on a stored app that restarts every few events and require equal states after every step; kill a process at every commit stage of an event that changes a number, a text and a list; and check frames, message atomicity and migration by restart and by replacement. A stored event costs about 10.6 ms more on the Pi's SD card, mostly two fsyncs.
* Add records, lists and indices to Pure moduleseunhhu2026-09-251-3/+3
| | | | | | | | | | | | Module format v4 declares record types and adds list states (items of a record) and index states (a position in one list). The verifier types record operands field by field and rejects an index used on another list. Indices follow their item across inserts and removes. List changes are logged per event and undone when the event fails. Replacing a module keeps a list by name and moves its fields by name when the record changed. pure-run prints lists as arrays and a failed view as null.
* Add text states and cursors to Pure moduleseunhhu2026-09-251-6/+10
| | | | | | | | | | | | | | | | | | | | | | Module format v3 adds text states, cursors, UTF-8 constants, text inputs and text views. A text state is a runtime-owned draft without a store, so a large text edits as an extent tree. Cursors are byte positions the runtime keeps on character boundaries: insertion pushes cursors at or after the point, removal gathers cursors inside the range, and a failed event returns every text draft and cursor to where it was. The verifier types a cursor by the text it belongs to and rejects editing one text with another's cursor. Operations cover constants, concatenation, shortest round-trip number text, character, line and byte counts, character and column-keeping line moves, insert, remove, line views, whole-text replacement and UTF-8 checked conversion from bytes. Replies of edited documents or texts are copied before they are finished. pure-run gains text input and text output. test-module covers typing Korean and emoji, moves that stop at the ends, line moves, views, rollback, invalid UTF-8 and replacement, text-specific verifier rules, and 20,000 damaged text modules whose cursors always stay on character boundaries under ASan/UBSan.
* Add typed messages and keyed documents to Pure moduleseunhhu2026-09-251-2/+6
| | | | | | | | | | | | | | | | | | | | Module format v2 adds byte values, message inputs with u32 and bytes-tail fields, one keyed byte collection, replies and require. The verifier checks every operand's type and the context each operation may run in, and allows branches and joins only at an empty stack, so typed values never merge. A message event opens its key's working version through a PureData host, conflicts early on a stale base revision, runs its handlers, and commits only if they succeed; a failed event leaves documents and states unchanged. Replies lend payload or document extents, and a document reply is copied before commit. pure_tree_data implements the host on tree store drafts, and pure-edit-module offers the document CLI contract of pure-edit from a module. test-module adds document semantics on an in-memory host (not found, create, conflict before bounds, limits, short payloads, busy commits, stable replies, require, state rollback), typed verifier rules, and 20,000 damaged message modules run safely under ASan/UBSan.
* Define Pure module format v1 with a static verifiereunhhu2026-09-251-1/+11
| | | | | | | | | | | | | | | Pure now owns the format its toolchains target, as the JVM owns class files. A v1 module carries f64 states, key inputs, atomic event handlers and pure views. pure_module_load checks sizes, names, keys, operands, forward-only branches, reachability and stack heights at every join before anything runs, so execution needs no stack checks and each event is bounded by its handler length. PureApp runs events on a pending copy and replaces modules keeping states by name, without allocation. Semantics match the workbench engine, including IEEE minimum/maximum on signed zeros. test-module covers behaviour, atomic faults, 26 rejection checks and 20,000 damaged modules under ASan/UBSan; pure-run is a JSON test host.
* Let the runtime own working versions as draftseunhhu2026-09-251-1/+1
| | | | | | | | | | | | | | | | | | state.h gives any app a runtime-owned working version of a stored value on the tree store. A draft shares unchanged extents with the stored version, edits in memory by path copying, lends ordered extents without copying, and commits only its new nodes when the key is still at its base revision. A failed commit changes neither the draft nor the store; a draft whose file was replaced by compaction copies its stored extents on commit. Unreachable arena nodes are reclaimed once they outweigh max(reachable, 32 KiB). Typing into the middle of a 1 MiB document and saving each character peaked at about 1,660 KiB RSS with a draft against about 4,480 KiB for an app copy compared with storage on save; saves were only 1-2 ms faster. This corrects 073, which had attributed the TUI's remaining 8 ms to that comparison. Drafts are not yet charged to the runtime budget or visible to .pure definitions.
* Add selected single-file persistent tree storeeunhhu2026-09-251-1/+12
| | | | | | | | | | | | | | | | store-tree.c keeps every document in one append-only file as a persistent B-tree of byte extents, with the key catalog in the same structure. A splice writes only the changed leaf and path; unchanged extents are shared between versions, readers take no lock, and two alternating head slots publish a commit after its nodes are durable. Compaction rewrites reachable nodes. On the recorded ext4 host a durable 1-byte middle insert into a 1 MiB document took 8.58 ms against 78.51 ms for the default store, and the real TUI's Ctrl+S after typing took 16.60 ms against 84.59 ms. check-tree runs the store's crash/oracle tests and the unchanged runtime, splice, async and real-PTY editor checks on it. It stays opt-in: linked code is 12.7 KB larger and contiguous multi-leaf reads copy.
* Move document key listing behind the store APIeunhhu2026-09-251-4/+7
| | | | | | | | | | The terminal editor listed documents by reading the flat store's obj- file names, so a UI host depended on one storage layout. pure_store_keys now lists keys through the selected store; per-object file stores share store-keys.c, linked only by hosts that browse documents, so the default CLI and HTTP hosts are unchanged. The source TUI ceiling reviews the measured 368-byte cost.
* Admit aligned OS pages in selected paged storeeunhhu2026-09-241-1/+7
|
* Establish native micro runtime checkpointeunhhu2026-09-241-0/+251