{"id":15017793,"url":"https://github.com/awncorp/zing","last_synced_at":"2025-04-09T19:42:46.448Z","repository":{"id":55371186,"uuid":"271602335","full_name":"awncorp/zing","owner":"awncorp","description":"Actor-Model Toolkit and Multi-Process Management System","archived":false,"fork":false,"pushed_at":"2021-02-12T17:30:01.000Z","size":398,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-23T21:45:44.586Z","etag":null,"topics":["actor-model","event-loop","ipc","job-queue","message-passing","perl","perl5"],"latest_commit_sha":null,"homepage":"https://metacpan.org/release/Zing","language":"Perl","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/awncorp.png","metadata":{"files":{"readme":"README","changelog":"CHANGES","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-06-11T17:04:18.000Z","updated_at":"2022-07-24T21:03:52.000Z","dependencies_parsed_at":"2022-08-14T22:42:05.138Z","dependency_job_id":null,"html_url":"https://github.com/awncorp/zing","commit_stats":null,"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awncorp%2Fzing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awncorp%2Fzing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awncorp%2Fzing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awncorp%2Fzing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/awncorp","download_url":"https://codeload.github.com/awncorp/zing/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248101230,"owners_count":21047931,"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":["actor-model","event-loop","ipc","job-queue","message-passing","perl","perl5"],"created_at":"2024-09-24T19:50:59.598Z","updated_at":"2025-04-09T19:42:46.428Z","avatar_url":"https://github.com/awncorp.png","language":"Perl","readme":"NAME\n\n    Zing - Actor-Model Toolkit\n\nABSTRACT\n\n    Actor Toolkit and Multi-Process Management System\n\nSYNOPSIS\n\n      use Zing;\n    \n      my $zing = Zing-\u003enew(scheme =\u003e ['MyApp', [], 1]);\n    \n      # $zing-\u003eexecute;\n\nDESCRIPTION\n\n    This distribution includes an actor-model architecture toolkit and\n    multi-process management system which provides primatives for building\n    resilient, reactive, concurrent, distributed message-driven\n    applications in Perl 5. If you're unfamiliar with this architectural\n    pattern, learn more about \"the actor model\"\n    \u003chttps://en.wikipedia.org/wiki/Actor_model\u003e.\n\nINHERITS\n\n    This package inherits behaviors from:\n\n    Zing::Kernel\n\nLIBRARIES\n\n    This package uses type constraints from:\n\n    Zing::Types\n\nATTRIBUTES\n\n    This package has the following attributes:\n\n scheme\n\n      scheme(Scheme)\n\n    This attribute is read-only, accepts (Scheme) values, and is required.\n\nMETHODS\n\n    This package implements the following methods:\n\n start\n\n      start() : Kernel\n\n    The start method prepares the Zing::Kernel and executes its event-loop.\n\n    start example #1\n\n        # given: synopsis\n      \n        $zing-\u003estart;\n\nPRIMATIVES\n\n    This distribution provides a collection of actor-model primitives which\n    can be used to create sophisticated and powerful distributed systems,\n    organized within intricate process topologies. The following is a\n    directory of those primitives listed by classification:\n\n messaging\n\n    These classes facilitate message-passing and communications:\n\n      * Zing::Channel: Shared Communication\n\n      * Zing::Data: Process Data\n\n      * Zing::Domain: Shared State\n\n      * Zing::KeyVal: Key/Value Store\n\n      * Zing::Lookup: Domain Index\n\n      * Zing::Table: Generic Index\n\n      * Zing::Mailbox: Process Mailbox\n\n      * Zing::PubSub: Pub/Sub Store\n\n      * Zing::Queue: Message Queue\n\n      * Zing::Registry: Process Registry\n\n      * Zing::Repo: Generic Store\n\n      * Zing::Store: Storage Abstraction\n\n processes\n\n    These base classes implement the underlying process (actor) logic:\n\n      * Zing: Process Wrapper\n\n      * Zing::Kernel: Kernel Process\n\n      * Zing::Launcher: Scheme Launcher\n\n      * Zing::Process: Processing Unit\n\n      * Zing::Ring: Process Ring\n\n      * Zing::Scheduler: Scheme Launcher\n\n      * Zing::Simple: Simple Process\n\n      * Zing::Single: Single Process\n\n      * Zing::Spawner: Scheme Spawner\n\n      * Zing::Timer: Timer Process\n\n      * Zing::Watcher: Watcher Process\n\n      * Zing::Worker: Worker Process\n\n stores\n\n    These classes handle data persistence for all messaging abstractions:\n\n      * Zing::Store::Disk: File-based Persistence\n\n      * Zing::Store::Hash: In-Memory Persistence\n\n      * Zing::Store::Mysql: MySQL Persistence\n\n      * Zing::Store::Pg: PostgreSQL Persistence\n\n      * Zing::Store::Redis: Redis Persistence\n\n      * Zing::Store::Sqlite: SQLite Persistence\n\n      * Zing::Store::Temp: Temporary File-based Persistence\n\n ready-made\n\n    These classes are ready-made process implementations using callbacks:\n\n      * Zing::Zang: Process Implementation\n\n      * Zing::Zang::Launcher: Process Launcher\n\n      * Zing::Zang::Simple: Process Performer\n\n      * Zing::Zang::Single: Single-Task Process\n\n      * Zing::Zang::Spawner: Process Spawner\n\n      * Zing::Zang::Timer: Timer Process\n\n      * Zing::Zang::Watcher: Process Watcher\n\n      * Zing::Zang::Worker: Worker Process\n\nFEATURES\n\n    All features are implemented using classes and objects. The following\n    is a list of features currently enabled by this toolkit:\n\n actor-model\n\n      use Zing::Process;\n    \n      my $p1 = Zing::Process-\u003enew;\n      my $p2 = Zing::Process-\u003enew;\n    \n      $p1-\u003esend($p2, { action =\u003e 'greetings' });\n    \n      say $p2-\u003erecv-\u003e{action}; # got it?\n\n    This distribution provides a toolkit for creating processes (actors)\n    which can be run in isolation and which communicate with other\n    processes through message-passing.\n\n asynchronous\n\n      # in process (1)\n      use Zing::Domain;\n      use Zing::Process;\n    \n      my $d1 = Zing::Domain-\u003enew(name =\u003e 'peers');\n      my $p1 = Zing::Process-\u003enew(name =\u003e 'p1');\n    \n      $d1-\u003epush('mailboxes', $p1-\u003emailbox-\u003eterm);\n      $p1-\u003eexecute;\n    \n      # in process (2)\n      use Zing::Domain;\n      use Zing::Process;\n    \n      my $d2 = Zing::Domain-\u003enew(name =\u003e 'peers');\n      my $p2 = Zing::Process-\u003enew(name =\u003e 'p2');\n    \n      my $mailboxes = $d2-\u003eget('mailboxes');\n    \n      for my $address (@$mailboxes) {\n        # send each registered process a message\n        $p2-\u003esend($address, { discovery =\u003e $p2-\u003emailbox-\u003eterm });\n      }\n    \n      $p2-\u003eexecute;\n\n    This distribution provides a multi-process management system which\n    allows processes to be deployed and managed separately having the\n    ability to communicate across threads of execution.\n\n atomicity\n\n      # in process (1)\n      use Zing::KeyVal;\n    \n      my $i = 0;\n      my $kv = Zing::KeyVal-\u003enew(name =\u003e 'stash');\n    \n      while ($i \u003c 1_000) {\n        $kv-\u003esend('random', { value =\u003e 1 });\n    \n        # my $data = $kv-\u003erecv('random');\n      }\n    \n      # in process (2)\n      use Zing::KeyVal;\n    \n      my $i = 0;\n      my $kv = Zing::KeyVal-\u003enew(name =\u003e 'stash');\n    \n      while ($i \u003c 1_000) {\n        $kv-\u003esend('random', { value =\u003e 2 });\n    \n        # my $data = $kv-\u003erecv('random');\n      }\n\n    This distribution provides data storage abstractions which perform\n    atomic reads and write by leveraging Redis \u003chttps://redis.io\u003e as the\n    default data storage backend.\n\n chainable\n\n      use Zing::Process;\n      use Zing::Ring;\n    \n      my $p1 = Zing::Process-\u003enew(name =\u003e 'p1');\n      my $p2 = Zing::Process-\u003enew(name =\u003e 'p2');\n    \n      my $ring = Zing::Ring-\u003enew(processes =\u003e [$p1, $p2]);\n    \n      $ring-\u003eexecute;\n\n    This distribution provides a mechanism for chaining (i.e. joining) two\n    or more processes together and executing them in a turn-based manner.\n    This ability allows you to design complex hierarchical process\n    topologies.\n\n channels\n\n      # in process (1)\n      use Zing::Channel;\n    \n      my $chan = Zing::Channel-\u003enew(name =\u003e 'chat');\n    \n      while (1) {\n        if (my $data = $chan-\u003erecv) {\n          # broadcast received\n          warn $data-\u003e{text};\n        }\n      }\n    \n      # in process (2)\n      use Zing::Channel;\n    \n      my $chan = Zing::Channel-\u003enew(name =\u003e 'chat');\n    \n      while (1) {\n        if (my $data = $chan-\u003erecv) {\n          # broadcast received\n          warn $data-\u003e{text};\n        }\n      }\n\n    This distribution provides the means for braodcasting and communicating\n    to multiple processes simulaneously through channels which are similar\n    to FIFO queues.\n\n clusterable\n\n      # in process (1) on cluster (1)\n      use Zing::Queue;\n    \n      my $queue = Zing::Queue-\u003enew(name =\u003e 'tasks', target =\u003e 'global');\n    \n      # pull from global queue\n      $queue-\u003erecv;\n    \n      # in process (1) on cluster (2)\n      use Zing::Queue;\n    \n      my $queue = Zing::Queue-\u003enew(name =\u003e 'tasks', target =\u003e 'global');\n    \n      # pull from global queue\n      $queue-\u003erecv;\n\n    This distribution provides support cross-cluster communication and thus\n    operations. Using federated Redis as the data storage backend means you\n    can scale your deployments without changing your implementations.\n\n configuration\n\n      # configure the namespace\n      ZING_NS=app\n    \n      # enable process debugging tracing\n      ZING_DEBUG=1\n    \n      # configure the namespace, same as ZING_NS (defaults to \"main\")\n      ZING_HANDLE=app\n    \n      # configure where the command-line tool finds catridges\n      ZING_HOME=/tmp\n    \n      # configure the hostname used in process registration\n      ZING_HOST=0.0.0.0\n      ZING_HOST=68.80.90.100\n    \n      # configure the resource target (e.g. when distributing across multiple hosts)\n      ZING_TARGET='global' # 'us-east', 'us-west', etc\n    \n      # configure the datastore (defaults to 'Zing::Store::Redis')\n      ZING_STORE='Zing::Store::Redis'\n    \n      # configure Redis driver without touching your source code\n      ZING_REDIS='server=127.0.0.1:6379'\n      ZING_REDIS='every=1_000_000,reconnect=60'\n      ZING_REDIS='sentinels=127.0.0.1:12345|127.0.0.1:23456,sentinels_cnx_timeout=0.1'\n      ZING_REDIS='server=192.168.0.1:6379,debug=0'\n    \n      # configure the object encoder (defaults to 'Zing::Encoder::Json')\n      ZING_ENCODER='Zing::Encoder::Json'\n    \n      # configure where the command-line tool finds catridges and PID files\n      ZING_APPDIR=./\n      ZING_PIDDIR=/tmp\n\n    This distribution provides environment variables that let you customize\n    how Zing operates and behaves without the need to modify source code.\n    These attributes are not required and fallback to sane defaults.\n\n distributed\n\n      # in process (1..n) on cluster (1)\n      use Zing;\n    \n      my $zing = Zing-\u003enew(scheme =\u003e ['MyApp', [], 16]);\n    \n      $zing-\u003eexecute;\n    \n      # in process (1..n) on cluster (2)\n      use Zing;\n    \n      my $zing = Zing-\u003enew(scheme =\u003e ['MyApp', [], 16]);\n    \n      $zing-\u003eexecute;\n    \n      # in process (1..n) on cluster (3)\n      use Zing;\n    \n      my $zing = Zing-\u003enew(scheme =\u003e ['MyApp', [], 16]);\n    \n      $zing-\u003eexecute;\n\n    This distribution provides a collection of actor-model primitives which\n    can be used to create sophisticated and powerful distributed systems,\n    organized within intricate process topologies.\n\n event-driven\n\n      # in process (1)\n      package MyApp::FileUpoad;\n    \n      use parent 'Zing::Process';\n    \n      sub receive {\n        my ($self, $from, $data) = @_;\n    \n        # react to file-upload events\n    \n        return;\n      }\n    \n      my $p1 = MyApp::FileUpoad-\u003enew;\n    \n      $p1-\u003eexecute;\n    \n      # in process (2)\n      package MyApp::TextTranslate;\n    \n      use parent 'Zing::Process';\n    \n      sub receive {\n        my ($self, $from, $data) = @_;\n    \n        # react to text-translate events\n    \n        return;\n      }\n    \n      my $p2 = MyApp::TextTranslate-\u003enew;\n    \n      $p2-\u003eexecute;\n\n    This distribution provides all the prerequisites needed to develop\n    scalable reactive event-driven applications distributed across one or\n    several servers.\n\n fifo-queues\n\n      # in process (1)\n      use Zing::Queue;\n    \n      my $queue = Zing::Queue-\u003enew(name =\u003e 'tasks');\n    \n      # pull from queue\n      $queue-\u003esend({ command =\u003e { ... } });\n      $queue-\u003esend({ command =\u003e { ... } });\n      $queue-\u003esend({ command =\u003e { ... } });\n      $queue-\u003esend({ command =\u003e { ... } });\n    \n      # in process (2)\n      use Zing::Queue;\n    \n      my $queue = Zing::Queue-\u003enew(name =\u003e 'tasks');\n    \n      # pull from FIFO queue\n      $queue-\u003erecv;\n\n    This distribution provides high-performance FIFO message queues which\n    enhance messaging across processes when the order of operations and\n    events is critical and where duplicates can't be tolerated.\n\n hot-reloadable\n\n      use Zing;\n      use Zing::Daemon;\n    \n      my $daemon = Zing::Daemon-\u003enew(\n        name =\u003e 'myapp-sleep',\n        app =\u003e Zing-\u003enew(scheme =\u003e ['MyApp::Sleep', [], 4])\n      );\n    \n      $daemon-\u003eexecute; # pid 12345\n    \n      # $ kill -USR2 12345\n\n    This distribution provides zero-downtime through hot-reloading which is\n    where the process watchers (supervisors) keep the app running and\n    gracefully reload child processes at runtime.\n\n log-shipping\n\n      use Zing::Zang;\n    \n      my $zang = Zing::Zang-\u003enew(on_perform =\u003e sub {\n        my ($self) = @_;\n    \n        $self-\u003elog-\u003efatal('something went wrong');\n    \n        return;\n      });\n    \n      $zang-\u003eexecute;\n    \n      # tap the logs using the command-line tool\n    \n      # $ zing logs\n\n    This distribution provides the ability to ship the logs of individual\n    processes to a specific centralized channel which can be tapped\n    asynchronously, especially by the command-line tool.\n\n mailboxes\n\n      use Zing::Process;\n    \n      my $p1 = Zing::Process-\u003enew(name =\u003e 'p1');\n      my $p2 = Zing::Process-\u003enew(name =\u003e 'p2');\n    \n      $p1-\u003emailbox-\u003esend($p2-\u003emailbox-\u003eterm, { say =\u003e 'ehlo' });\n    \n      my $message = $p2-\u003emailbox-\u003erecv;\n    \n      $p2-\u003emailbox-\u003ereply($message, { say =\u003e 'helo' });\n\n    This distribution provides every process with its own unique mailbox\n    which can receive messages from other processes as a means of\n    cooperating through message passing.\n\n management\n\n      use Zing::Kernel;\n    \n      my $kernel = Zing::Kernel-\u003enew(scheme =\u003e ['MyApp::Logger', [], 2]);\n    \n      $kernel-\u003eexecute;\n\n    This distribution provides a kernel process that can be used to manage\n    the deployment of child processes and is used to wrap cartridges by the\n    command-line tool when daemonizing process.\n\n multitasking\n\n      use Zing::Zang;\n    \n      my $zang = Zing::Zang-\u003enew(\n        on_perform =\u003e sub {\n          # do something\n        },\n        on_receive =\u003e sub {\n          # handle something\n        },\n      );\n    \n      $zang-\u003eexecute;\n\n    This distribution provides all processes with an event-loop that allows\n    them to perform multiple operations in sequence and supports operating\n    in a non-blocking manner.\n\n non-blocking\n\n      use Zing::Zang;\n    \n      my $zang = Zing::Zang-\u003enew(\n        on_perform =\u003e sub {\n          my ($self) = @_;\n    \n          $self-\u003edefer({ command =\u003e {...} }) and return;\n    \n          return;\n        },\n        on_receive =\u003e sub {\n          my ($self, $from, $data) = @_;\n    \n          return unless $self-\u003eterm eq $from; # from myself\n    \n          # do something\n    \n          return;\n        }\n      );\n    \n      $zang-\u003eexercise;\n\n    This distribution provides features that allow processes to operate in\n    a non-blocking manner, yielding and deferring operations, and chunking\n    workloads.\n\n parallelism\n\n      use Zing::Process;\n    \n      my $p1 = Zing::Process-\u003enew;\n    \n      my $f1 = $p1-\u003espawn(['MyApp', [id =\u003e 12345] 1]);\n      my $f2 = $p1-\u003espawn(['MyApp', [id =\u003e 12346] 1]);\n\n    This distribution provides multiple ways of executing operations in\n    parallel, including spawning processes via forking with the guarantee\n    of not creating zombie processes.\n\n supervisors\n\n      use Zing::Zang::Watcher;\n    \n      my $zang = Zing::Zang::Watcher-\u003enew(\n        scheme =\u003e ['MyApp', [] 8]\n      );\n    \n      $zang-\u003eexercise;\n\n    This distribution provides watcher processes which to supervise child\n    processes but also are capable of multitasking and performing other\n    operations while monitoring supervised processes.\n\n virtual-actors\n\n      use Zing::Zang::Spawner;\n    \n      my $zang = Zing::Zang::Spawner-\u003enew(\n        queues =\u003e ['schemes']\n      );\n    \n      $zang-\u003eexercise;\n\n    This distribution provides the ability to use virtual actors, which are\n    processes (actors) created on-demand as a result of some system event.\n    This feature is enabled by the Zing::Launcher and Zing::Spawner\n    superclasses.\n\nCOMMANDS\n\n    Given the following process (actor):\n\n      # in lib/MyApp.pm\n    \n      package MyApp;\n    \n      use parent 'Zing::Single';\n    \n      sub perform {\n        # do something (once)\n      }\n    \n      1;\n\n    With an application cartridge specifying 4 forks:\n\n      # in app/myapp\n    \n      ['MyApp', [], 4]\n\n    The zing command-line application lets you manage Zing applications\n    from the command-line using these commands:\n\n start\n\n      $ zing start app/myapp\n\n    The start command loads an application cartridge which returns a\n    \"scheme\" and runs it as a daemon.\n\n stop\n\n      $ zing stop app/myapp\n\n    The stop command finds a running application by its PID (process ID)\n    and terminates the process.\n\n logs\n\n      $ zing logs --level fatal\n\n    The logs command taps the centralized log source and outputs new events\n    to STDOUT (standard output).\n\nSEE ALSO\n\n    The Actor Model \u003chttps://en.wikipedia.org/wiki/Actor_model\u003e\n\n    Concurrent Computation\n    \u003chttps://www.amazon.com/Actors-Concurrent-Computation-Distributed-Systems/dp/026251141X\u003e\n\n    Concurrency in Go/Erlang \u003chttps://www.youtube.com/watch?v=2yiKUIDFc2I\u003e\n\n    The Akka Project \u003chttps://github.com/akka/akka\u003e\n\n    The Actorkit Project \u003chttps://github.com/influx6/actorkit\u003e\n\n    The Orleans Project \u003chttp://dotnet.github.io/orleans\u003e\n\n    The Pyakka Project \u003chttps://github.com/jodal/pykka\u003e\n\n    The Reactive Manifesto \u003chttp://www.reactivemanifesto.org\u003e\n\nDISCLOSURES\n\n    The following is a list of all the known ways Zing is not like a\n    traditional actor-model system:\n\n      * In Zing, actors act independently and aren't beholden to a system\n      manager.\n\n      * In Zing, actors are always active (each runs its own infinite\n      event-loop).\n\n      * In Zing, actors can communicate unrestricted (no approved\n      communicators).\n\n      * In Zing, actors can block using poll but do not block by default.\n\n      * In Zing, the system responsible for persistence and atomicity is\n      pluggable and as such is subject to the guarantees and limitations of\n      that underlying system. Data serialization, e.g. JSON\n      \u003chttps://json.org\u003e, is also pluggable.\n\nAUTHOR\n\n    Al Newkirk, awncorp@cpan.org\n\nLICENSE\n\n    Copyright (C) 2011-2019, Al Newkirk, et al.\n\n    This is free software; you can redistribute it and/or modify it under\n    the terms of the The Apache License, Version 2.0, as elucidated in the\n    \"license file\" \u003chttps://github.com/cpanery/zing/blob/master/LICENSE\u003e.\n\nPROJECT\n\n    Wiki \u003chttps://github.com/cpanery/zing/wiki\u003e\n\n    Project \u003chttps://github.com/cpanery/zing\u003e\n\n    Initiatives \u003chttps://github.com/cpanery/zing/projects\u003e\n\n    Milestones \u003chttps://github.com/cpanery/zing/milestones\u003e\n\n    Contributing\n    \u003chttps://github.com/cpanery/zing/blob/master/CONTRIBUTE.md\u003e\n\n    Issues \u003chttps://github.com/cpanery/zing/issues\u003e\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fawncorp%2Fzing","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fawncorp%2Fzing","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fawncorp%2Fzing/lists"}