{"id":15502179,"url":"https://github.com/gonzalo-bulnes/inter_process_communication_demo","last_synced_at":"2025-03-29T14:15:29.573Z","repository":{"id":27973646,"uuid":"31466941","full_name":"gonzalo-bulnes/inter_process_communication_demo","owner":"gonzalo-bulnes","description":"Playing with named pipes in Ruby.","archived":false,"fork":false,"pushed_at":"2015-03-01T04:51:11.000Z","size":256,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-03-27T04:14:17.392Z","etag":null,"topics":["demo","inter-process-communication","ruby"],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"ChenhanYu/hmlp","license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gonzalo-bulnes.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-02-28T15:44:58.000Z","updated_at":"2021-11-15T09:56:29.000Z","dependencies_parsed_at":"2022-08-26T12:21:19.219Z","dependency_job_id":null,"html_url":"https://github.com/gonzalo-bulnes/inter_process_communication_demo","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gonzalo-bulnes%2Finter_process_communication_demo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gonzalo-bulnes%2Finter_process_communication_demo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gonzalo-bulnes%2Finter_process_communication_demo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gonzalo-bulnes%2Finter_process_communication_demo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gonzalo-bulnes","download_url":"https://codeload.github.com/gonzalo-bulnes/inter_process_communication_demo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246193257,"owners_count":20738452,"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":["demo","inter-process-communication","ruby"],"created_at":"2024-10-02T09:08:39.585Z","updated_at":"2025-03-29T14:15:29.551Z","avatar_url":"https://github.com/gonzalo-bulnes.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"Demo: Inter-process Communication\n=================================\n\nAn example Ruby program to be used as a proof of concept for inter-process commnication between a _main_ program which needs to delegate hooks processing and a _worker_ program which performs those hooks.\n\nIdea\n----\n\nThe first example uses [named pipes][np] to allow the _main_ program to delegate one hook to the _worker_.\n\nThe second example was an attempt to use [signals][sig] to allow the _worker_ to peform multiple hooks depending on the _main_ program needs. The attempt failed.\n\nThe third example succeeds at performing an arbitrary number of hooks by [forking][fork] the _worker_, thus allowing it to read from a _named pipe_ as long as the _main_ program is running.\n\n  [np]: https://en.wikipedia.org/wiki/Named_pipe\n  [sig]: https://en.wikipedia.org/wiki/Unix_signal\n  [fork]: https://en.wikipedia.org/wiki/Fork_%28system_call%29\n\nUsage\n-----\n\n_Note: for now, there are no signals involved._\n\nInstall dependencies, using [RVM][rvm] is optional but strongly recommended:\n\n```bash\n# trigger the RVM hooks so the gems get installed in an dedicated gemset\ncd inter_process_communication_demo\n\n# install dependencies\nbundle install\n```\n\n  [rvm]: https://rvm.io\n\n### Basic named pipes\n\nCreate the _named pipes_ that will be used by `main.rb` and `worker.rb` to communicate:\n\n```bash\ncd lib/01_basic_named_pipes\n\n# create a named pipe for the main program to notify\n# the worker about a hook to be performed\nmkfifo main_to_worker\n\n# create another named pipe for the worker to reply\n# to the main program\nmkfifo worker_to_main\n\n# once you're done using them, remove both pipes:\n#rm main_to_worker worker_to_main\n```\n\nIn the fist scenario, the worker is waiting for hook requests:\n\n```bash\n# Scenario 1\n\n# start the worker\nruby worker.rb # will wait until there is a hook to perform\n\n# in a distinct terminal, start the main program\nruby main.rb # since the worker is available, the hook is performed immediately\n```\n\nIn the second scenario, the main program is waiting for workers to be available:\n\n```bash\n# Scenario 2\n\n# start the main program\nruby main.rb # will wait until a wroker preforms the hook\n\n# in a distinct terminal, start the worker\nruby worker.rb # since a hook request was performed, performs the hook immediately\n```\n\n### Signals\n\n**Note**: Signals don't seem to be the way to go, see these [signals limitations][signals].\n\nThe idea was having a `worker_on_demand`, which would start the `main` program (provinding its own PID to it).\nThe main program would sent a signal each time a hook would need to be performed.\n\n```bash\ncd lib/02_signals\n\n# start\nruby worker_on_demand.rb # multiple hook requests are handled by the worker\n```\n\n### Named pipes and fork\n\nThe first example has two limitations:\n- only one hook request can be handled by the worker\n- the main program and the worker must agree on two named pipes to communicate\n\nTo be able to handle any number of hook requests, the worker must be able to loop while the main program is running. Of course, it should exit once the main program has exited.\n\nIn order to do so, let's introduce the `worker_provider` program. It will start a looping worker, then start the main program, and make sure the worker exits when the main program does. It will also provide both named pipes to both the worker and the main program.\n\n```bash\ncd lib/03_named_pipes_and_fork\n\n# start the worker provider program\nruby worker_provider.rb # will start a worker and a main program with several hooks to perform\n```\n\nReferences\n----------\n\n- [Using Named Pipes in Ruby for Inter-process Communication][dix]\n- [Ruby 2.2.0 documentation: Process][doc]\n- [Forking and IPC in Ruby, Part II][fk]\n\n  [dix]: http://www.pauldix.net/2009/07/using-named-pipes-in-ruby-for-interprocess-communication.html\n  [fk]: http://www.sitepoint.com/forking-ipc-ruby-part-ii\n  [signals]: https://github.com/gonzalo-bulnes/inter_process_communication_demo/blob/add-signal-handling-to-handle-multiple-hooks/lib/02_signals/on_demand_worker.rb#L48-L56\n  [doc]: http://ruby-doc.org/core-2.2.0/Process.html\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgonzalo-bulnes%2Finter_process_communication_demo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgonzalo-bulnes%2Finter_process_communication_demo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgonzalo-bulnes%2Finter_process_communication_demo/lists"}