{"id":19281814,"url":"https://github.com/scality/arsenal","last_synced_at":"2026-04-09T19:22:51.702Z","repository":{"id":9082573,"uuid":"42728835","full_name":"scality/Arsenal","owner":"scality","description":"Common utilities for the open-source Scality S3 project components","archived":false,"fork":false,"pushed_at":"2025-08-06T11:06:26.000Z","size":9610,"stargazers_count":16,"open_issues_count":41,"forks_count":20,"subscribers_count":53,"default_branch":"development/8.2","last_synced_at":"2025-08-06T13:05:23.742Z","etag":null,"topics":["artesca","object","ring","zenko"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/scality.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","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,"zenodo":null}},"created_at":"2015-09-18T14:58:21.000Z","updated_at":"2025-08-01T15:36:48.000Z","dependencies_parsed_at":"2024-02-19T09:44:10.283Z","dependency_job_id":"7397713d-d95c-4a1a-a082-d020b22d2dbe","html_url":"https://github.com/scality/Arsenal","commit_stats":null,"previous_names":[],"tags_count":784,"template":false,"template_full_name":null,"purl":"pkg:github/scality/Arsenal","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scality%2FArsenal","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scality%2FArsenal/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scality%2FArsenal/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scality%2FArsenal/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/scality","download_url":"https://codeload.github.com/scality/Arsenal/tar.gz/refs/heads/development/8.2","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scality%2FArsenal/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270385016,"owners_count":24574537,"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","status":"online","status_checked_at":"2025-08-14T02:00:10.309Z","response_time":75,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["artesca","object","ring","zenko"],"created_at":"2024-11-09T21:24:19.308Z","updated_at":"2026-04-09T19:22:51.656Z","avatar_url":"https://github.com/scality.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Arsenal\n\n[![badgepub]](https://github.com/scality/Arsenal/actions/workflows/tests.yaml)\n[![codecov]](https://codecov.io/gh/scality/Arsenal)\n\nCommon utilities for the S3 project components\n\nWithin this repository, you will be able to find the shared libraries for the\nmultiple components making up the whole Project.\n\n* [Guidelines](#guidelines)\n* [Shuffle](#shuffle) to shuffle an array.\n* [Errors](#errors) load an object of errors instances.\n    - [errors/arsenalErrors.json](errors/arsenalErrors.json)\n\n## Guidelines\n\nPlease read our coding and workflow guidelines at\n[scality/Guidelines](https://github.com/scality/Guidelines).\n\n### Contributing\n\nIn order to contribute, please follow the\n[Contributing Guidelines](\nhttps://github.com/scality/Guidelines/blob/master/CONTRIBUTING.md).\n\n## Shuffle\n\n### Usage\n\n``` js\nimport { shuffle } from 'arsenal';\n\nlet array = [1, 2, 3, 4, 5];\n\nshuffle(array);\n\nconsole.log(array);\n\n//[5, 3, 1, 2, 4]\n```\n\n## Errors\n\n### Usage\n\n``` js\nimport { errors } from 'arsenal';\n\nconsole.log(errors.AccessDenied);\n\n//{ [Error: AccessDenied]\n//    code: 403,\n//    description: 'Access Denied',\n//    AccessDenied: true }\n\n```\n\n## Build Status\n\n![badgepub]\n\n## Codecov Status\n\n![codecov]\n\n## Clustering\n\nThe clustering class can be used to set up a cluster of workers. The class will\ncreate at least 1 worker, will log any worker event (started, exited).\nThe class also provides a watchdog which restarts the workers in case of\nfailure until the stop() method is called.\n\n### Usage\n\n#### Simple\n\n```\nimport { Clustering } from 'arsenal';\n\nconst cluster = new Clustering(clusterSize, logger);\ncluster.start(current =\u003e {\n    // Put here the logic of every worker.\n    // 'current' is the Clustering instance, worker id is accessible by\n    // current.getIndex()\n});\n```\n\nThe callback will be called every time a worker is started/restarted.\n\n#### Handle exit\n\n```\nimport { Clustering } from 'arsenal';\n\nconst cluster = new Clustering(clusterSize, logger);\ncluster.start(current =\u003e {\n    // Put here the logic of every worker.\n    // 'current' is the Clustering instance, worker id is accessible by\n    // current.getIndex()\n}).onExit(current =\u003e {\n    if (current.isMaster()) {\n        // Master process exiting\n    } else {\n        const id = current.getIndex();\n        // Worker (id) exiting\n    }\n});\n```\n\nYou can handle exit event on both master and workers by calling the\n'onExit' method and setting the callback. This allows release of resources\nor save state before exiting the process.\n\n#### Silencing a signal\n\n```\nimport { Clustering } from 'arsenal';\n\nconst cluster = new Clustering(clusterSize, logger);\ncluster.start(current =\u003e {\n    // Put here the logic of every worker.\n    // 'current' is the Clustering instance, worker id is accessible by\n    // current.getIndex()\n}).onExit((current, signal) =\u003e {\n    if (signal !== 'SIGTERM') {\n        process.exit(current.getStatus());\n    }\n});\n```\n\nYou can silence stop signals, by simply not exiting on the exit callback\n\n#### Shutdown timeout\n\n```\nimport { Clustering } from 'arsenal';\n\nconst cluster = new Clustering(clusterSize, logger, 1000);\ncluster.start(current =\u003e {\n    // Put here the logic of every worker.\n    // 'current' is the Clustering instance, worker id is accessible by\n    // current.getIndex()\n}).onExit((current, signal) =\u003e {\n    if (signal === 'SIGTERM') {\n        // releasing resources\n    }\n});\n```\n\nBy default, the shutdown timeout is set to 5000 milliseconds. This timeout is\nused only when you explicitly call the stop() method. This window is\nused to let the application release its resources, but if timeout occurs\nbefore the application has finished it's cleanup, a 'SIGKILL' signal is send\nto the process (which results in an immediate termination, and this signal\ncan't be caught).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscality%2Farsenal","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fscality%2Farsenal","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscality%2Farsenal/lists"}