Handing off Maintenance of Partisan
I’m happy to announce that I am handing off maintenance of Partisan, the distributed runtime system I built as part of my Ph.D. (and my first paper published at CMU!), to Alejandro Ramallo at Leapsight.
Alejandro has done tremendous work on Partisan over the last two years: from fixing bugs, feature enhancement to performance improvements.
Alejandro has also brought Partisan to places that, as a PhD student who works mostly in a lab, never imagined: LO/JACK LATAM, the lost vehicle recovery service, since 2019, has been using Partisan as part of its Magenta Platform, tracking 300k vehicles, 10k devices, receiving over 30M GPS transmissions each day!
At LO/JACK LATAM, Leapsight uses Partisan as a foundational component for:
- Magenta Twin Service: an IoT twins implementation using a modified version of Erleans, an implementation of the Microsoft Orlean’s virtual actor model for Erlang, modified to use PlumDB for metadata and state storage and Partisan for transport.
- Magenta Agent Service: an IoT Rule-based system built using PlumDB and Partisan.
You can learn more about how it’s used here:
Industrial Usage
Leapsight has used Partisan as the backbone of two of their products:
- Bondy, an open source, always-on and scalable application networking platform for modern architectures. Bondy is an all-in-one event and service mesh that offers both Publish-Subscribe (PubSub) and routed Remote Procedure Calls (RPC). Bondy implements the open Web Application Messaging Protocol (WAMP) and is written in Erlang.
- PlumDB, a database globally replicated via Epidemic Broadcast Trees and lasp-lang’s Partisan. An offspring of Plumtree and Partisan, a descendant of Riak Core Metadata Store.
Future Plans
Alejandro has a lot in store for Partisan:
- API usage
- Add remote monitoring support of the local node using partisan.
- Allowing the parallelism setting to apply in a per-channel, not global, setting.
- Normalize all APIs to use the URI encoded remote pids, references, and node names.
- Feature: Casual delivery
- Disk-based storage for failover.
- Implement reliabile causal broadcast
- Maintenance: Overlay Tree Construction
- One
partisan_plumtree_broadcastserver per channel to increase throughput - Explore allowing concurrent access to broadcast members by making
partisan_plumtree_broadcastserver useets - Implement Thicket
- One
- General improvements
- OTP 25 support
- QUIC Transport
Changelog
Since Alejandro is hard at work on getting 5.0.0 release of Partisan prepared, I include the incredibly long list of changes, bug fixes, and improvements planned for the next week that him and his team completed over the last two years.
Thanks Alejandro and LeapSight!
CHANGELOG
v5.0.0 (beta)
API
In general, the API was redesigned to concentrate all functions around two modules: partisan and partisan_peer_service.
Changes
partisanmodule was repurposed as a replacement for theerlangmodule for use cases related to distribution e.g.erlang:nodes/0->partisan:nodes/0.- Several functions previously found in
partisan_peer_service,partisan_monitorandpartisan_utilare now in this module:partisan:broadcast/2partisan:cast_message/3partisan:cast_message/4partisan:cast_message/5partisan:default_channel/0partisan:demonitor/1partisan:demonitor/2partisan:forward_message/2partisan:forward_message/3partisan:forward_message/4partisan:forward_message/5partisan:is_connected/1partisan:is_connected/2partisan:is_fully_connected/1partisan:is_local/1partisan:is_pid/1partisan:is_process_alive/1partisan:is_reference/1partisan:make_ref/0partisan:monitor/1partisan:monitor/2partisan:monitor/3partisan:monitor_node/2partisan:monitor_nodes/1partisan:monitor_nodes/2partisan:node/0partisan:nodestring/0partisan:node/1partisan:node_spec/0partisan:node_spec/1partisan:node_spec/2partisan:nodes/0partisan:nodes/1partisan:self/0partisan:send_message/2
- Several functions previously found in
- Added the following functions:
partisan_peer_service:broadcast_members/0partisan_peer_service:broadcast_members/1partisan_peer_service:cancel_exchanges/1partisan_peer_service:exchanges/0partisan_peer_service:exchanges/1partisan_peer_service:get_local_state/0partisan_peer_service:inject_partition/2partisan_peer_service:leave/1partisan_peer_service:member/1partisan_peer_service:members_for_orchestration/0partisan_peer_service:on_down/2partisan_peer_service:on_up/2partisan_peer_service:partitions/0partisan_peer_service:reserve/1partisan_peer_service:resolve_partition/1partisan_peer_service:update_members/1
- Use of
partisan_peer_service:mynode/0has been replaced bypartisan:node/0to follow Erlang convention - Use of
partisan_peer_service:myself/0has been replaced bypartisan:node_spec/0to disambiguate frompartisan:node/0. - Use of
Nodevariable name fornode()type (as opposed toName) andNodeSpecfornode_spec()(as opposed toNode) to disambiguate. - Adde new module
partisan_rpcthat will provide and API that mirrors Erlangsrpcanderpcmodules - Added
partisan_remote_refto encapsulate the creation of reference and added an optional/alternative representation for encoded pids, references and registered names. The module offers all the functions to convert pids, references and names to/from Partisan encoded references.-
Alternative representation: In cases where lots of references are stored in process state, ets and specially where those are uses as keys, a binary format is preferable to the tuple format in order to save memory usage and avoid copying the term every time a message is send between processes.
partisan_remote_refrepresents an encoded reference as binary URI. This is controlled by the config optionremote_ref_as_uriandremote_ref_binary_paddingin case the resulting URIs are smaller than 65 bytes.1> partisan_remote_ref:from_term(self()). {partisan_remote_reference,nonode@nohost,{partisan_process_reference,"<0.1062.0>"}} 2> partisan_config:set(remote_ref_as_uri, true). ok 3> partisan_remote_ref:from_term(self()). <<"partisan:pid:nonode@nohost:0.1062.0">> 4> partisan_config:set(remote_ref_binary_padding, true). ok 5> partisan_remote_ref:from_term(self()). <<"partisan:pid:nonode@nohost:0.1062.0:"...>>
-
Peer Membership
Fixes
- Replaced the use of
state_orsetCRDT withstate_awmapto avoid an issue where a node will crash and restart with a different IP address e.g. when deploying in K8s. As the membership set containsnode_spec()objects which contain the IP address we ended up with duplicate entries for the node. Thestate_awmaptries to solve that by mapping anode() => state_mvregister(node_spec()) - Fixes several bugs related to the
leaveoperation inpartisan_pluggable_peer_service_manager:- Added a missing call to update the membership set during leave
- Fixed a concurrency issue whereby on self leave the peer service server will restart before being able to sending the new state with the cluster peers and thus the node would remain as a member in all other nodes.
- Resolves an issue
partisan_plumtree_broadcastwhere theall_membersset was not updated when a member is removed. - Resolves the issue where the
partisan_plumtree_broadcastwas not removing the local node from the broadcast member set. - Gen Behaviours take new option
channelif defined. - Fixed implementation of
on_upandon_downcallback functions inpartisan_pluggable_peer_service_manager
Changes
- Added function
partisan_peer_service_manager:member/1 - Replaced the use of in-process sets in
plumtree_broadcast_backendwith anetstable for outstanding messages keeping the gen_server stack lean and avoiding garbage collection
Peer Connection management
Fixes
- Fixes a bug where connections where not properly kill during a leave
- Split TLS options for client and server roles
- Removed
tls_options - Added
tls_client_optionsandtls_server_options
- Removed
Changes
- New module
peer_service_connectionsreplaces the former process state data structure and thepartisan_connection_cachemodule. It offers an ets-based solution with use of counters for quick node connection status check partisan_peer_connectionshas been re-implemented to use ets to increase perfomance and remove the need for an additional caching feature.- As a result, the
partisan_connection_cachemodule has been was removed. - Checking connection status is now a fast
etslookup operation and leveragesets:update_counter/4,ets:lookup_element/3andets:select_count/2to handle concurreny and minimise copying data into the caller’s process heap.
- As a result, the
Process and Peer Monitoring
Fixes
- A more complete/safe implementation of process monitoring in
partisan_monitor. - More robust implementation of monitors using the new subscription capabilities provided by
peer_serviceon_upandon_downcallback functions.- monitor a node or all nodes
- use node monitors to signal a process monitor when the remote node is disconnected
- avoid leaking monitors
- new supervisor to ensure that
partisan_monitoris restarted every time the configuredpartisan_peer_service_manageris restarted.
Changes
- New api in
partisanmodule following the same name, signature and semantics of theirerlangandnet_kernelmodules counterparts:partisan:monitor/1partisan:monitor/2partisan:monitor/3partisan:monitor_node/2partisan:monitor_nodes/1partisan:monitor_nodes/2
OTP compatibility
Fixes
Changes
- Partisan now requires OTP24 or later.
- Upgraded
partisan_genandpartisan_gen_serverto match their OTP24 counterparts implementation - Added
partisan_gen_statem partisan_gen_fsmdeprecated as it was not complete and focus was given to the implementation ofpartisan_gen_stateminstead- Module
partisan_mochiglobalhas been removed and replaced bypersistent_term
Misc
Fixes
- Most existing
INFOlevel logs have been reclassified asDEBUG - Fixed types specifications in various modules
Changes
lagerdependency has been removed and all logging is done using the new Erlanglogger- Most uses of the
orddictmodule have been replaced by maps for extra performance and better usability - Most API options using
proplistsmodule have been replaced by maps for extra performance and better usability - In several functions the computation of options (merging user provided with defaults, validation, etc.) has been posponed until (and only if) it is needed for extra performance e.g.
partisan_pluggable_peer_servie_manager:forward_message - More utils in
partisan_util - Added
ex_doc(Elixir documentation) rebar plugin - Upgraded the following dependencies:
uuidtypes- rebar plugins