{"id":24385697,"url":"https://github.com/salsferrazza/cquencer","last_synced_at":"2026-04-26T01:33:15.100Z","repository":{"id":273009842,"uuid":"907857191","full_name":"salsferrazza/cquencer","owner":"salsferrazza","description":"A central sequence number server","archived":false,"fork":false,"pushed_at":"2025-12-30T22:42:05.000Z","size":151,"stargazers_count":0,"open_issues_count":3,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-12-31T17:45:50.226Z","etag":null,"topics":["atomicbroadcast","broadcast","eventsourcing","multicast","sequencer","sequencerarchitecture","totalordering","udp","unicast","virtualsynchrony"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/salsferrazza.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-12-24T15:06:57.000Z","updated_at":"2025-12-30T22:41:19.000Z","dependencies_parsed_at":"2025-01-18T02:34:30.672Z","dependency_job_id":"27cf659b-dfd8-47da-bd32-6881477630c4","html_url":"https://github.com/salsferrazza/cquencer","commit_stats":null,"previous_names":["salsferrazza/cquencer"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/salsferrazza/cquencer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/salsferrazza%2Fcquencer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/salsferrazza%2Fcquencer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/salsferrazza%2Fcquencer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/salsferrazza%2Fcquencer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/salsferrazza","download_url":"https://codeload.github.com/salsferrazza/cquencer/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/salsferrazza%2Fcquencer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32283294,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-25T18:29:39.964Z","status":"ssl_error","status_checked_at":"2026-04-25T18:29:32.149Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["atomicbroadcast","broadcast","eventsourcing","multicast","sequencer","sequencerarchitecture","totalordering","udp","unicast","virtualsynchrony"],"created_at":"2025-01-19T11:29:02.677Z","updated_at":"2026-04-26T01:33:15.072Z","avatar_url":"https://github.com/salsferrazza.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# cquencer\n_A central sequence number server_\n\n## Synopsis\n\nThe `cquencer` is a standalone central sequence number server, embodying the \"Fixed Sequencer\" \nordering mechanism described by [Défago, et al](https://infoscience.epfl.ch/server/api/core/bitstreams/068f8add-50ce-4216-b750-3cde412ee397/content) (2004). \n\n\u003cimg width=\"2126\" height=\"1146\" alt=\"image\" src=\"https://github.com/user-attachments/assets/953d9c36-3f9d-4a72-b29b-54ceaa3c543f\" /\u003e\n\n`cquencer` adheres to a simple protocol and is payload-agnostic. It\nlistens for connections over TCP on a local address and port. Each message received over that port is assigned a\nsequence number and both the sequence number and the original message\npayload are published to the specified multicast group over UDP. \n\n## Rationale\n\nThe `cquencer` authors are proponents of the [Sequencer\nArchitecture](https://electronictradinghub.com/an-introduction-to-the-sequencer-world/])\ncommonly found in electronic trading systems. While adjacent patterns\nsuch as [event-sourcing](https://martinfowler.com/eaaDev/EventSourcing.html) have gained traction in recent years, we are of\nthe opinion that the world could use more advocacy and open-source tooling to\nmore clealry illustrate the benefits of sequencer architectures. \n\nThe currently available options tend to be commercial or attached to a\nlarger solution that does much more than sequencing. Additionally,\nthe existing tools bias toward Java as a host language. There are no\nclear options for a network message sequencer unbundled from a larger or more vertically-specific package. \n\nEnter `cquencer`.\n\n`cq`, the sequencer binary, compiles to just over 50K. It's job:\naccept bytes over TCP, prepend a sequence number to those bytes, and\nsend the sequenced bytes to its specified multicast group.\n\n## Protocol\n\nThe `cquencer` accepts any data over its TCP port as a discrete\nmessage.\n\nTCP clients, upon sequencing of the message, are returned an\nASCII-encoded sequence number as the only response. Messages sent with\nno content are returned the current sequence number and do not mutate\nthe stream.\n\nThe message sent to the multicast group is framed as a nested [netstring](https://en.wikipedia.org/wiki/Netstring). The entire contents of the multicast message is itself a netstring that is composed of two child netstrings. The first child netstring contains the sequence number. The second child netstring contains the original message bytes, undisturbed. For example:\n\nTCP Sender:\n```\n% bin/sendr 3001\n? \u003cRET\u003e \n# 5:85636,\n? hello world\n# 5:88485,\n? \n```\n\nUDP Destination:\n```\n% bin/destn 239.0.0.1 1234\n23:5:88485,11:hello world,,\n```\n\n## Why netstring?\n\nOne principle of `cquencer` is that there should be no need for the sequencer to inspect or modify the contents of any message payloads submitted. Thus, where to apply the sequence number of outbound sequenced messages becomes a challenge to overcome. \n\nLength-prefixed binary was the initial instinct for output encoding, and functionally this approach would be most efficient. However, it is possible that developers who are not accustomed to dealing with binary encodings may find that an obstacle to getting started, especially if the message payloads they are currently represented as text.\n\nNetstrings might be viewed as training wheels for length-prefixed binary encodings. The length and payload delimiters are in plain-text and easy to keep track of visually while sniffing network traffic or inspecting messages saved to a file. The use of netstrings doesn't preclude employing binary encoding of message payloads, so applications may leverage their existing encodings without adjustments. Developers new to sequencer architecture will likely find netstring encoding easier to work with as opposed to binary length-prefixing.\n\nThe ability to nest netstrings provided a simple, clear solution for representing sequence numbers alongside the originally submitted payload, without having to crack messages open affirmatively to prepend a sequence number.  This allows the sequenced message to retain the bit identity of the original payload, without interfering with any requisite hash or checksum validation of submitted messages downstream.\n\nHowever, netstrings do come with several drawbacks. The first is efficiency. Netstring encodings simply require more bytes on the wire than an equivalent binary encoding. In particular, the delimiters being represented with ASCII characters add several bytes to each message. \n\nIn addition, netstring payloads yield more variability in the size of payloads per message. For example, a value of `1` encoded as a netstring yields:\n\n```\n1:1,\n```\n\nwhich is four bytes. The equivalent binary value would always yield 10 bytes (eight for the 64-bit integer + two for the length prefix) on the wire. For values in the lower range, netstrings are actually more compact on the wire. This assessment, though, ignores the additional encoding and decoding compute required at the source and destination. \n\nHowever, As the sequence number increases, the footprint on the sequenced netstring also increases.  The maximum value of a 64-bit unsigned integer is `18446744073709551615`. As a netstring, this becomes:\n\n```\n20:18446744073709551615,\n```\n\nWhich increases the footprint of the transmitted netstring to 24 bytes. A binary encoding would remain at 10 bytes throughout the entire range of values sent over the wire.\n\nFuture revisions of `cquencer` will look to parameterize encoding strategies such that users may select from a choice of codecs for sequenced messages. \n\n## Building `cquencer`\n\n```\n% cd cquencer\n%  make\nmkdir -p bin\nrm -f bin/*\ngcc -Wall -Werror -o bin/cq src/cq.c src/vector.c\ngcc -Wall -Werror -o bin/destn src/destn.c\ngcc -Wall -Werror -o bin/sendr src/sendr.c\n% ls -l bin\ntotal 248\n-rwxr-xr-x  1 sal  staff  52848 Aug  3 16:26 cq\n-rwxr-xr-x  1 sal  staff  34024 Aug  3 16:26 destn\n-rwxr-xr-x  1 sal  staff  34472 Aug  3 16:26 sendr\n%\n```\n\n## Usage\n\n- `cq` is the sequencer binary. \n\n```\ncq: a fixed sequencer for atomic broadcast\n\nUsage: cq \u003ctcp port\u003e \u003cmulticast group\u003e \u003cmulticast port\u003e\n  Messages submitted over TCP are multicast\n  to the specified group and port, using nested\n  netstring framing\n  ```\n\n- `destn` is an example multicast destination that logs all received\n  data to `STDOUT`\n\n\n`destn \u003cmulticast group IP\u003e \u003cmulticast group port\u003e`\n\n- `sendr` is a shell that allows for interactive submission of\n  plain-text messages.\n\n`sendr \u003cport of sequencer process\u003e` \n\n## Acknowledgements\n\n## See also\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsalsferrazza%2Fcquencer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsalsferrazza%2Fcquencer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsalsferrazza%2Fcquencer/lists"}