{"id":20464469,"url":"https://github.com/bytedance/ipmb","last_synced_at":"2025-04-04T13:10:00.187Z","repository":{"id":181116826,"uuid":"666245816","full_name":"bytedance/ipmb","owner":"bytedance","description":"An interprocess message bus system built in Rust.","archived":false,"fork":false,"pushed_at":"2025-03-10T15:15:35.000Z","size":241,"stargazers_count":85,"open_issues_count":1,"forks_count":11,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-03-28T12:06:53.722Z","etag":null,"topics":["cpp","ipc","message-bus","nodejs","rust"],"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/bytedance.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2023-07-14T03:53:11.000Z","updated_at":"2025-03-25T06:01:22.000Z","dependencies_parsed_at":"2024-07-17T09:28:22.704Z","dependency_job_id":"cee59d26-47f3-4af0-b4a4-7577592d1271","html_url":"https://github.com/bytedance/ipmb","commit_stats":null,"previous_names":["bytedance/ipmb"],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bytedance%2Fipmb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bytedance%2Fipmb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bytedance%2Fipmb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bytedance%2Fipmb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bytedance","download_url":"https://codeload.github.com/bytedance/ipmb/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247182357,"owners_count":20897379,"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":["cpp","ipc","message-bus","nodejs","rust"],"created_at":"2024-11-15T13:15:18.984Z","updated_at":"2025-04-04T13:10:00.170Z","avatar_url":"https://github.com/bytedance.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ctable\u003e\n   \u003ctr\u003e\n      \u003ctd align=\"center\"\u003e\n         \u003cimg src=\"logo.png\" width=\"25%\"\u003e\n\nAn interprocess message bus system built in Rust, which can be used to pass messages between multiple processes, even including kernel objects (HANDLE/MachPort/FD).\n      \u003c/td\u003e\n   \u003c/tr\u003e\n\u003c/table\u003e\n\n[![Crates.io](https://img.shields.io/crates/v/ipmb.svg?label=ipmb)](https://crates.io/crates/ipmb)\n[![npm version](https://img.shields.io/npm/v/ipmb-js.svg?label=ipmb-js)](https://www.npmjs.com/package/ipmb-js)\n\n## Goals\n\n- **Easy to use**: `join`, `send`, `recv`, that's everything\n- **Bus architecture**: No server or client, messages can be freely transmitted among multiple endpoints\n- **Message typing**: An endpoint can send or receive multiple message types simultaneously without all endpoints defining a complete global message structure\n- **Practical features**: Object, Memory Region, Selector and so on\n\n## Getting Started\n\n```toml\n[dependencies]\nipmb = \"0.8\"\n```\n\n`earth.rs`:\n```rust\nuse ipmb::label;\n\nfn main () -\u003e Result\u003c(), Box\u003cdyn Error\u003e\u003e {\n    // Join your bus \n    let options = ipmb::Options::new(\"com.solar\", label!(\"earth\"), \"\");\n    let (sender, receiver) = ipmb::join::\u003cString, String\u003e(options, None)?;\n\n    // Receive messages\n    while let Ok(message) = receiver.recv(None) {\n        log::info!(\"received: {}\", message.payload);\n    }\n    Ok(())\n}\n```\n\n`moon.rs`:\n```rust\nuse ipmb::label;\nuse std::thread;\nuse std::time::Duration;\n\nfn main () -\u003e Result\u003c(), Box\u003cdyn Error\u003e\u003e {\n    // Join your bus \n    let options = ipmb::Options::new(\"com.solar\", label!(\"moon\"), \"\");\n    let (sender, receiver) = ipmb::join::\u003cString, String\u003e(options, None)?;\n\n    loop {\n        // Create a message\n        let selector = ipmb::Selector::unicast(\"earth\");\n        let mut message = ipmb::Message::new(selector, \"hello world\".to_string());\n\n        // Send the message\n        sender.send(message)?;\n        \n        thread::sleep(Duration::from_secs(1));\n    }\n}\n```\n## Concepts\n\n### Identifier\n\nAn identifier is a system-level unique name for a bus, and only endpoints on the same bus can communicate with each other. \nOn macOS, it will be used to register the MachPort service, on Windows, it will be used to create the corresponding named pipe, \nand on Linux, it will be used to bind abstract socket address.\n\n### Label\n\nLabel is the description of an endpoint, and a message can be routed to an endpoint with a `LabelOp`.\nA label can contain multiple elements, such as `label!(\"renderer\", \"codec\")`.\n\n### Selector\n\nSelector is used to describe the routing rules of the message, which consists of 2 parts:\n\n1. **SelectorMode**: Specify how to consume the message when multiple endpoints satisfy routing rules at the same time. \n    - `Unicast`: Only one endpoint can consume this message\n    - `Multicast`: All endpoints can consume this message\n2. **LabelOp**: Describe the matching rules of label, and supports logical operations of AND/OR/NOT.\n\n### Payload\n\nPayload is the body content of a message, and its type can be specified by the type parameter of the join function.\nYou can define your own message types:\n\n```toml\n[dependencies]\ntype-uuid = \"0.1.2\"\n```\n\n```rust\nuse serde::{Deserialize, Serialize};\nuse type_uuid::TypeUuid;\n\n#[derive(Debug, Serialize, Deserialize, TypeUuid)]\n#[uuid = \"7b07473e-9659-4d47-a502-8245d71c0078\"]\nstruct MyMessage {\n    foo: i32,\n    bar: bool,\n}\n\nfn main() -\u003e Result\u003c(), Box\u003cdyn Error\u003e\u003e {\n    let (sender, receiver) = ipmb::join::\u003cMyMessage, MyMessage\u003e(..)?;\n    Ok(())\n}\n```\n\n### MessageBox\n\nMessageBox is a container for multiple message types, allowing endpoints to send/receive multiple message types.\n\n```rust\nuse ipmb::MessageBox;\n\n#[derive(MessageBox)]\nenum MultipleMessage {\n   String(String),\n   I32(i32),\n   MyMessage(MyMessage),\n}\n\nfn main() -\u003e Result\u003c(), Box\u003cdyn Error\u003e\u003e {\n    let (sender, receiver) = ipmb::join::\u003cMultipleMessage, MultipleMessage\u003e(..)?;\n    Ok(())\n}\n```\n\n### Object\n\nObject is the kernel object representation, MachPort on macOS, HANDLE on Windows, FD on Linux, ipmb supports sending Object as message attachment to other endpoints.\n\n```rust\nfn main () {\n   let mut message = ipmb::Message::new(..);\n   let obj = unsafe { ipmb::Object::from_raw(libc::mach_task_self()) };\n   message.objects.push(obj);\n}\n```\n\n### MemoryRegion\n\nMemoryRegion is a shared memory block, ipmb supports sending MemoryRegion as message attachment to other endpoints without copying.\n\n```rust\nfn main() -\u003e Result\u003c(), Box\u003cdyn Error\u003e\u003e{\n   let mut message = ipmb::Message::new(..);\n   let mut region = ipmb::MemoryRegion::new(16 \u003c\u003c 10);\n   let view = region.map(..)?;\n   writeln!(view, \"Hello\")?;\n   message.memory_regions.push(region);\n   Ok(())\n}\n```\n\n### MemoryRegistry\n\nEfficiently performs many MemoryRegions allocation by sharing and reusing MemoryRegions.\n\n```rust\nfn main() {\n   let mut registry = ipmb::MemoryRegistry::default();\n   // Alloc memory region from the registry\n   let mut region = registry.alloc(8 \u003c\u003c 20, None);\n}\n```\n\n## Language Bindings\n\n1. **C/C++**: `ipmb-ffi` provides `ipmb_ffi.h`/`ipmb.h`, prebuilt libraries can be downloaded [here](https://github.com/xiaopengli89/ipmb/releases)\n2. **Node.js**: `ipmb-js` provides node package ([![npm version](https://img.shields.io/npm/v/ipmb-js.svg?label=ipmb-js)](https://www.npmjs.com/package/ipmb-js))\n\n## Supported Platforms\n\n| Platform |     |\n|----------|-----|\n| macOS    | ✅  |\n| Windows  | ✅  |\n| Linux    | ✅  |\n\n## Benchmark \n\nIntel(R) Core(TM) i7-9750H CPU @ 2.60GHz, macOS 13.4\n\n```\n[2023-06-29T08:54:48Z INFO  bench]       16 B    752,469/s    12.0 MB/s\n[2023-06-29T08:54:48Z INFO  bench]       64 B    437,096/s    28.0 MB/s\n[2023-06-29T08:54:48Z INFO  bench]     1.0 KB    412,224/s   422.1 MB/s\n[2023-06-29T08:54:48Z INFO  bench]     4.1 KB    327,748/s     1.3 GB/s\n[2023-06-29T08:54:49Z INFO  bench]    16.4 KB     33,261/s   544.9 MB/s\n```\n\n## License\n\nipmb is dual-licensed:\n\n- [MIT license](LICENSE.MIT)\n- [Apache License, Version 2.0](LICENSE.APACHE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbytedance%2Fipmb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbytedance%2Fipmb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbytedance%2Fipmb/lists"}