{"id":13507146,"url":"https://github.com/fishcakez/sbroker","last_synced_at":"2025-04-05T13:09:12.499Z","repository":{"id":24328970,"uuid":"27726065","full_name":"fishcakez/sbroker","owner":"fishcakez","description":"Sojourn-time based active queue management library","archived":false,"fork":false,"pushed_at":"2019-06-13T07:10:40.000Z","size":789,"stargazers_count":162,"open_issues_count":0,"forks_count":9,"subscribers_count":8,"default_branch":"master","last_synced_at":"2024-05-16T23:24:25.424Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://hexdocs.pm/sbroker/","language":"Erlang","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/fishcakez.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-12-08T17:21:18.000Z","updated_at":"2024-04-18T17:20:25.000Z","dependencies_parsed_at":"2022-08-22T16:30:08.408Z","dependency_job_id":null,"html_url":"https://github.com/fishcakez/sbroker","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fishcakez%2Fsbroker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fishcakez%2Fsbroker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fishcakez%2Fsbroker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fishcakez%2Fsbroker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fishcakez","download_url":"https://codeload.github.com/fishcakez/sbroker/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247339158,"owners_count":20923014,"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-08-01T02:00:25.163Z","updated_at":"2025-04-05T13:09:12.477Z","avatar_url":"https://github.com/fishcakez.png","language":"Erlang","funding_links":[],"categories":["Actors","Other"],"sub_categories":["Scientific Computing"],"readme":"sbroker\n=======\n\n`sbroker` is a library that provides the building blocks for creating a pool\nand/or a load regulator. The main goals of the library are to minimise upper\npercentile latency by smart queuing, easily change the feature set live with\nminimal changes, easily inspect a live system and provide confidence with\nproperty based testing.\n\nExample\n-------\n\nAdd a broker to the `sbroker` application env `brokers` and it will be started\nwhen the application starts. Below we use a CoDel queue for the `ask` side, a\ntimeout queue for the `ask_r` side and no meters. Processes then call\n`sbroker:ask/1` and `sbroker:ask_r` to find a match. A process calling\n`sbroker:ask/1` will only match with a process that calls `sbroker:ask_r` and\nvice versa.\n\n```erlang\nok = application:load(sbroker),\nBroker = broker,\nBrokers = [{{local, Broker},\n            {{sbroker_codel_queue, #{}}, {sbroker_timeout_queue, #{}}, []}}],\nok = application:set_env(sbroker, brokers, Brokers),\n{ok, _} = application:ensure_all_started(sbroker).\n\nPid = spawn_link(fun() -\u003e {go, Ref, _, _, _} = sbroker:ask_r(Broker) end),\n{go, Ref, Pid, _, _} = sbroker:ask(Broker).\n```\n\nMatches can also be requested without queuing, asynchronously or using a dynamic\napproach that is synchronous but becomes asynchronous if a match isn't\nimmediately available.\n\nRequirements\n------------\n\nThe minimum OTP version supported is 18.0.\n\nThe `sasl` application is required to start the `sbroker` application. The\n`sasl` `error_logger` handler can be disabled by setting the `sasl` application\nenv `sasl_error_logger` to `false`.\n\nInstalling\n----------\n\nFor rebar3 add `sbroker` as a depencency in `rebar.config`:\n\n```erlang\n{deps, [sbroker]}.\n```\n\nOther build tools may work if they support `rebar3` dependencies but are not\ndirectly supported.\n\nTesting\n-------\n\n```\n$ rebar3 ct\n```\n\nDocumentation\n-------------\n\nDocumentation is hosted on hex: http://hexdocs.pm/sbroker/\n\n\nMotivation\n----------\n\nThe main roles of a pool are: dispatching, back pressure, load shedding,\nworker supervision and resizing.\n\nExisting pooling solutions assume if a worker is alive it is ready to handle\nwork. If a worker isn't ready a client must wait for it be ready, or error\nimmediately, when another worker might be ready to successfully handle the\nrequest. If workers explicitly control when they can are available then the\npool can always dispatch to workers that are ready.\n\nTherefore in an ideal situation clients are requesting workers and workers are\nrequesting clients. This is the broker pattern, where both parties are\nrequesting a match with the counter party. For simplicity the same API can be\nused for both and so to the broker both parties are clients.\n\nExisting pooling solutions that support back pressure use a timeout mechanism\nwhere clients are queued for a length of time and then give up. Once clients\nstart timing out, the next client in the queue is likely to have waited close to\nthe time out. This leads to the situation where clients are all queued for\napproximately the time out, either giving up or getting a worker. If clients\nthat give up could give up sooner then all clients would spend less time waiting\nbut the same number would be served.\n\nTherefore in an ideal situation a target queue time would be chosen that keeps\nthe system feeling responsive and clients would give up at a rate such that in\nthe long term clients spend up to the target time in the queue. This is sojourn\n(queue waiting) time active queue management. CoDel and PIE are two state of the\nart active queue management algorithms with a target sojourn time, so should\nuse those with defaults that keep systems feeling responsive to a user.\n\nExisting pooling solutions that support load shedding do not support back\npressure. These use ETS as a lock system and choose a worker to try. However\nother workers might be available but are not tried or busy wait is used to retry\nmultiple times to gain a lock. If clients could use ETS to determine whether\na worker is likely to be available we could use existing dispatch and back\npressure mechanisms.\n\nTherefore we want to limit access to the dispatching process by implementing a\nsojourn time active queue management algorithm using ETS in front of the\ndispatching process. Fortunately this is possible with the basic version of PIE.\n\nExisting pooling solutions either don't support resize or grow the pool when no\nworkers are immediately available. However that worker may need to setup an\nexpensive resource and is unlikely to be ready immediately. If workers are\nstarted early then the pool will be less likely to have no workers available.\n\nHowever the same pools that start workers \"too late\" also start new workers for\nevery client that tries to checkout when no workers are available. However old\nworkers will become available again, perhaps before new workers are ready. This\noften leads to too many workers getting started and wastes resources until they\nare reaped for being idle. If workers are started at intervals then temporary\nbursts would not start too many workers but persistent increases would still\ncause adequate growth.\n\nTherefore we want workers to be started when worker availability is running low\nbut with intervals between starting workers. This can be achieved by sampling\nthe worker queue at intervals and starting a worker based on the reading. This\nis the load regulator pattern, where the concurrency limit of tasks changes\nbased on sampling. For simplicity the same API as the broker could be used,\nwhere the regulator is also the counterparty to the workers.\n\nExisting pooling solutions that also support resizing use a temporary a\nsupervisor and keep restarting workers if they crash, equivalent to using max\nrestarts infinity. Unfortunately these pools can't recover from faults due to\nbad state because the error does not bubble up the supervision tree and trigger\nrestarts. They are \"too fault tolerant\" because the error does not spread far\nenough to trigger recovery. A pool where workers crash every time is not useful.\n\nTherefore we want workers to be supervised using supervisors with any\nconfiguration so the user can decide exactly how to handle failures. Fortunately\nusing both the broker and regulator patterns allows workers to be started under\nuser defined supervisors.\n\nLicense\n-------\n\nCopyright 2014 James Fish\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\nRoadmap\n-------\n\n* 1.1 - Add circuit breaker sregulator valves\n* 1.2+ - Add improved queue management algorithms when possible, if at all\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffishcakez%2Fsbroker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffishcakez%2Fsbroker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffishcakez%2Fsbroker/lists"}