{"_id":"@coorpacademy/cluster-sticky","_rev":"128-9f75c56520416aec6bfcae12a330f172","name":"@coorpacademy/cluster-sticky","dist-tags":{"latest":"4.1.0"},"versions":{"4.1.0":{"name":"@coorpacademy/cluster-sticky","version":"4.1.0","keywords":["sticky","session","listen","recluster","balancer"],"author":{"name":"Loïc Calvy","email":"lc@coorpacademy.com"},"license":"MIT","_id":"@coorpacademy/cluster-sticky@4.1.0","maintainers":[{"name":"coorpadmin","email":"system@coorpacademy.com"}],"homepage":"https://github.com/coorpacademy/cluster-sticky#readme","bugs":{"url":"https://github.com/coorpacademy/cluster-sticky/issues"},"dist":{"shasum":"8c584aabdd78df1085ebcf28ae697e2914d1e05a","tarball":"https://registry.npmjs.org/@coorpacademy/cluster-sticky/-/cluster-sticky-4.1.0.tgz","integrity":"sha512-qeh8WtjMdXXLKpxyMh5i5Zqg9cAR0PgRPDM/wsvdMRQ1hMtNitCU7VWS4TTA12PlDk1fprKTrC2zNC4y6jK5/A==","signatures":[{"sig":"MEUCIDxVCHxPOWVle1w3P+34jGzy5HHB+EpKDe5rIbY0DCpHAiEA/y8OndxrfIfHGzVC+lm+ODx8T2U7prDb3V3QeoDooMI=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","_shasum":"8c584aabdd78df1085ebcf28ae697e2914d1e05a","engines":{"node":">= 0.12.0"},"gitHead":"73c74a46a4c6f1a03ee0952308db61e4d612c619","scripts":{"lint":"eslint lib test index.js","test":"npm run lint && npm run test:back","test:back":"NPM_ENV=test mocha 'test/**/*Spec.js'"},"_npmUser":{"name":"coorpadmin","email":"system@coorpacademy.com"},"repository":{"url":"git+https://github.com/coorpacademy/cluster-sticky.git","type":"git"},"_npmVersion":"3.8.9","description":"Sticky listener based on Spion 's sticky-listen","directories":{"test":"test"},"_nodeVersion":"6.2.0","dependencies":{"debug":"^2.2.0"},"devDependencies":{"mocha":"^2.5.3","eslint":"^2.10.2","recluster":"^0.4.3","@coorpacademy/eslint-plugin-coorpacademy":"^1.1.2"},"_npmOperationalInternal":{"tmp":"tmp/cluster-sticky-4.1.0.tgz_1464189054137_0.7128497122321278","host":"packages-12-west.internal.npmjs.com"}}},"time":{"created":"2016-05-25T15:10:56.631Z","modified":"2026-08-03T13:31:35.888Z","4.1.0":"2016-05-25T15:10:56.631Z"},"bugs":{"url":"https://github.com/coorpacademy/cluster-sticky/issues"},"author":{"name":"Loïc Calvy","email":"lc@coorpacademy.com"},"license":"MIT","homepage":"https://github.com/coorpacademy/cluster-sticky#readme","keywords":["sticky","session","listen","recluster","balancer"],"repository":{"url":"git+https://github.com/coorpacademy/cluster-sticky.git","type":"git"},"description":"Sticky listener based on Spion 's sticky-listen","maintainers":[{"email":"silouane.galinou.dev@gmail.com","name":"silou"},{"email":"system@coorpacademy.com","name":"coorpadmin"},{"email":"eric.sampaio@coorpacademy.com","name":"esa-coorp"},{"email":"adriean.khisbe@live.fr","name":"adriean.khisbe"},{"email":"adams.roy27@gmail.com","name":"adamska27"},{"email":"djamel.soualmi@coorpacademy.com","name":"djamelsoualmi"},{"email":"elena.morana@coorpacademy.com","name":"emorana"},{"email":"emeline.leduc@coorpacademy.com","name":"emeline75"},{"email":"phuoc.tran@go1.com","name":"phuoctran8801"},{"email":"aung.maw@go1.com","name":"aung-go1"},{"email":"adams.roy@go1.com","name":"adamska28"},{"email":"chris.dugne@uralys.com","name":"chrisdugne"}],"readme":"# cluster-sticky [![Build Status](https://travis-ci.org/CoorpAcademy/cluster-sticky.svg?branch=master)](https://travis-ci.org/CoorpAcademy/cluster-sticky)\n\nA simple performant way to use socket.io with [recluster][recluster], based on\nSpion's sticky-listen.\n\nThis fork was motivated by needs to handle:\n- high performance balancer\n- multi proxy forwarded header\n- use in complex production environment with several threads, dynos (heroku) and cloudflare cdn\n- stronlgy tested\n## Installation\n\n```bash\nnpm install @coorpacademy/sticky-listen\n```\n\n## Usage\n\nIn your `cluster.js` that uses [recluster][recluster], use `sticky.createBalancer`\nto create a sticky balancing server.\n\n```js\nvar recluster = require('recluster'),\n    path = require('path'),\n    sticky = require('sticky-listen')\n\nvar cluster = recluster(path.join(__dirname, 'server.js'), {\n  readyWhen: 'ready',\n  workers: 2 // #cpus, default is require('os').cpus().length\n});\n\ncluster.run();\n\nprocess.on('SIGUSR2', function() {\n    console.log('Got SIGUSR2, reloading cluster...');\n    cluster.reload();\n});\n\nconsole.log(\"spawned cluster, kill -s SIGUSR2\", process.pid, \"to reload\");\n\n// Added for the sticky listener:\n\nvar balancer = sticky.createBalancer({\n  behindProxy: false,\n  activeWorkers: cluster.activeWorkers,\n  maxRetries: 5,\n  retryDelay: 100\n});\n\nbalancer.listen(8081, function() {\n  console.log(\"Sticky balancer listening on port\", 8081);\n});\n\n```\n\nIn your `server.js`, use `sticky.listen` instead of `server.listen` to start the server,\nthen use `process.send({cmd: 'ready'})` to indicate that the worker is ready.\n\n```javascript\nvar sticky = require('sticky-listen');\n\nvar server = require('http').createServer(function(req, res) {\n  res.end('worker: ' + process.env.NODE_WORKER_ID);\n});\n\nsticky.listen(server)\n\nprocess.send({cmd: 'ready'})\n```\n\n## Acknowledgement\n\nThis module is based on Spion's [sticky-listen][sticky-listen] but it simplify hash management.\n\n## API\n\n### sticky.listen(server)\n\nFor use from the worker process\n\nListens for sticky connections from a worker server. The port doesn't need\nto be specified.\n\n### sticky.createBalancer(options)\n\nFor use from the master process\n\nCreates a new master balancer server that balances between worker servers.\n\nReturns a regular `net.Server`. Call server.listen(port) to start listening\nfor connections and balancing those connections across the cluster.\n\nSticky sessions are achieved based on the IP address of the client - requests\nfrom the same IP are redirected to the same worker index.\n\nThe available options are\n\n##### `activeWorkers`\n\nA function that returns a hash of the worker slots. For recluster based\nbalancers that would be `cluster.activeWorkers`. The hash should contain:\n\n* a field `length`, the number of worker slots that serve requests\n* for every key `0..length`, a field that contains a [worker object][api-cluster-worker]\n  of a worker that is capable of receiving new connections. If a worker isn't\n  ready at that slot, the field should be `null`\n\n\n##### `retryDelay`\n\nIf there are no worker available to serve the client, retry finding one after\n`retryDelay` miliseconds.\n\n##### `maxRetries`\n\nThe number of retries to attempt before giving up and sending a 502 Bad Gateway\nerror to the client.\n\n##### `behindProxy`\n\nIf you use this option, sticky-listen will read the headers and look for\n`x-forwarded-for` when reading the IP address of the client. This enables the\nbalancer to work well even behind proxies such as HAProxy or nginx.\n\n## LICENSE\n\nThis software is licensed under the MIT License.\n\n\nCopyright Fedor Indutny, 2015; Gorgi Kosev, 2015; Loïc Calvy, 2016\n\nPermission is hereby granted, free of charge, to any person obtaining a\ncopy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to permit\npersons to whom the Software is furnished to do so, subject to the\nfollowing conditions:\n\nThe above copyright notice and this permission notice shall be included\nin all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\nOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\nNO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\nDAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\nOTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\nUSE OR OTHER DEALINGS IN THE SOFTWARE.\n\n[recluster]: https://github.com/doxout/recluster\n[api-cluster-worker]: https://nodejs.org/api/cluster.html#cluster_class_worker\n[sticky-session]: (https://github.com/indutny/sticky-session)\n[sticky-listen]: (https://github.com/indutny/sticky-listen)\n","readmeFilename":"README.md"}