{"id":13503044,"url":"https://github.com/servo/ipc-channel","last_synced_at":"2025-03-29T13:30:40.180Z","repository":{"id":34113396,"uuid":"37943142","full_name":"servo/ipc-channel","owner":"servo","description":"A multiprocess drop-in replacement for Rust channels","archived":false,"fork":false,"pushed_at":"2025-03-04T02:03:30.000Z","size":1029,"stargazers_count":938,"open_issues_count":54,"forks_count":134,"subscribers_count":25,"default_branch":"main","last_synced_at":"2025-03-28T13:04:07.513Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/servo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-APACHE","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}},"created_at":"2015-06-23T20:28:18.000Z","updated_at":"2025-03-28T10:30:11.000Z","dependencies_parsed_at":"2022-09-05T22:40:45.965Z","dependency_job_id":"5eaa4dbb-12b8-4029-9aba-71bf73b52abc","html_url":"https://github.com/servo/ipc-channel","commit_stats":{"total_commits":472,"total_committers":53,"mean_commits":8.90566037735849,"dds":0.527542372881356,"last_synced_commit":"7f432aab1eb77bb2c860881153799087918558e9"},"previous_names":[],"tags_count":28,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/servo%2Fipc-channel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/servo%2Fipc-channel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/servo%2Fipc-channel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/servo%2Fipc-channel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/servo","download_url":"https://codeload.github.com/servo/ipc-channel/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246190184,"owners_count":20737987,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-07-31T22:02:34.740Z","updated_at":"2025-03-29T13:30:40.165Z","avatar_url":"https://github.com/servo.png","language":"Rust","funding_links":[],"categories":["Rust","Programming"],"sub_categories":["Rust 🦀"],"readme":"`ipc-channel` is an inter-process implementation of Rust channels (which were inspired by CSP[^CSP]).\n\nA Rust channel is a unidirectional, FIFO queue of messages which can be used to send messages between threads in a single operating system process.\nFor an excellent introduction to Rust channels, see [Using Message Passing to Transfer Data Between Threads](https://doc.rust-lang.org/stable/book/ch16-02-message-passing.html) in the Rust reference. \n\n`ipc-channel` extends Rust channels to support inter-process communication (IPC) in a single operating system instance. The `serde` library is used to serialize and deserialize messages sent over `ipc-channel`.\n\nAs much as possible, `ipc-channel` has been designed to be a drop-in replacement for Rust channels. The mapping from the Rust channel APIs to `ipc-channel` APIs is as follows:\n\n* `channel()` → `ipc::channel().unwrap()`\n* `Sender\u003cT\u003e` → `ipc::IpcSender\u003cT\u003e` (requires `T: Serialize`)\n* `Receiver\u003cT\u003e` → `ipc::IpcReceiver\u003cT\u003e` (requires `T: Deserialize`)\n\nNote that both `IpcSender\u003cT\u003e` and `IpcReceiver\u003cT\u003e` implement `Serialize` and `Deserialize`, so you can send IPC channels over IPC channels freely, just as you can with Rust channels.\n\nThe easiest way to make your types implement `Serialize` and `Deserialize` is to use the `serde_macros` crate from crates.io as a plugin and then annotate the types you want to send with `#[derive(Deserialize, Serialize])`. In many cases, that's all you need to do — the compiler generates all the tedious boilerplate code needed to serialize and deserialize instances of your types.\n\n## Semantic differences from Rust channels\n\n* Rust channels can be either unbounded or bounded whereas ipc-channels are always unbounded and `send()` never blocks.\n* Rust channels do not consume OS IPC resources whereas ipc-channels consume IPC resources such as sockets, file descriptors, shared memory segments, named pipes, and such like, depending on the OS.\n* Rust channels transfer ownership of messages whereas ipc-channels serialize and deserialize messages.\n* Rust channels are type safe whereas ipc-channels depend on client and server programs using identical message types (or at least message types with compatible serial forms).\n\n## Bootstrapping channels between processes\n\n`ipc-channel` provides a one-shot server to help establish a channel between two processes. When a one-shot server is created, a server name is generated and returned along with the server.\n\nThe client process calls `connect()` passing the server name and this returns the sender end of an ipc-channel from\nthe client to the server. Note that there is a restriction in `ipc-channel`: `connect()` may be called at most once per one-shot server.\n\nThe server process calls `accept()` on the server to accept connect requests from clients. `accept()` blocks until a client has connected to the server and sent a message. It then returns a pair consisting of the receiver end of the ipc-channel from client to server and the first message received from the client.\n\nSo, in order to bootstrap an IPC channel between processes, you create an instance of the `IpcOneShotServer` type, pass the resultant server name into the client process (perhaps via an environment variable or command line flag), and connect to the server in the client. See `spawn_one_shot_server_client()` in `integration_test.rs` for an example of how to do this using a command to spawn the client process and `cross_process_embedded_senders_fork()` in `test.rs` for an example of how to do this using Unix `fork()`[^fork] to create the client process.\n\n## Testing\n\nTo run the tests, issue:\n\n```console\ncargo test\n```\n\nSome tests are platform dependent, so for completeness it would be necessary to run the tests on all platforms:\n\n* iOS\n* macOS†\n* Unix variants:\n  * Android\n  * FreeBSD\n  * Illumos\n  * Linux (Ubuntu†)\n  * OpenBSD\n* WASI\n* Windows†\n\nThe platforms marked † are covered by CI.\n\nTo run the benchmarks, issue:\n\n```console\ncargo bench\n```\n\n## Implementation overview\n\n`ipc-channel` is implemented in terms of native IPC primitives: file descriptor passing over Unix sockets on Unix variants, Mach ports on macOS, and named pipes on Windows.\n\nOne-shot server names are implemented as a file system path (for Unix variants, with the file system path bound to the socket) or other kinds of generated names on macOS and Windows.\n\n## Major missing features\n\n* Each one-shot server accepts only one client connect request. This is fine if you simply want to use this API to split your application up into a fixed number of mutually untrusting processes, but it's not suitable for implementing a system service. An API for multiple clients may be added later if demand exists for it.\n\n## Related\n\n* [Rust channel](https://doc.rust-lang.org/std/sync/mpsc/index.html): MPSC (multi-producer, single-consumer) channels in the Rust standard library. The implementation\nconsists of a single consumer wrapper of a port of Crossbeam channel.\n* [Crossbeam channel](https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-channel): extends Rust channels to be more like their Go counterparts. Crossbeam channels are MPMC (multi-producer, multi-consumer)\n* [Channels](https://docs.rs/channels/latest/channels/): provides Sender and Receiver types for communicating with a channel-like API across generic IO streams.\n\n[^CSP]: Tony Hoare conceived Communicating Sequential Processes (CSP) as a concurrent programming language.\nStephen Brookes and A.W. Roscoe developed a sound mathematical basis for CSP as a process algebra.\nCSP can now be used to reason about concurrency and to verify concurrency properties using model checkers such as FDR4.\nGo channels were also inspired by CSP.\n\n[^fork]: `fork()` has a number of semantic rough edges and is not recommended for general use. See \"A fork() in the road\" by Andrew Baumann _et al._, Proceedings of the Workshop on Hot Topics in Operating Systems, ACM, 2019. ([PDF](https://www.microsoft.com/en-us/research/uploads/prod/2019/04/fork-hotos19.pdf))\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fservo%2Fipc-channel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fservo%2Fipc-channel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fservo%2Fipc-channel/lists"}