{"id":20389307,"url":"https://github.com/positiondev/hworker-ses","last_synced_at":"2025-03-04T23:44:44.087Z","repository":{"id":35805499,"uuid":"40087488","full_name":"positiondev/hworker-ses","owner":"positiondev","description":null,"archived":false,"fork":false,"pushed_at":"2017-10-09T16:56:27.000Z","size":20,"stargazers_count":2,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-15T10:02:32.129Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/positiondev.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2015-08-02T17:43:10.000Z","updated_at":"2018-07-24T19:00:58.000Z","dependencies_parsed_at":"2022-09-15T04:02:31.017Z","dependency_job_id":null,"html_url":"https://github.com/positiondev/hworker-ses","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/positiondev%2Fhworker-ses","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/positiondev%2Fhworker-ses/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/positiondev%2Fhworker-ses/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/positiondev%2Fhworker-ses/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/positiondev","download_url":"https://codeload.github.com/positiondev/hworker-ses/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241940539,"owners_count":20045878,"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-11-15T03:17:17.764Z","updated_at":"2025-03-04T23:44:44.057Z","avatar_url":"https://github.com/positiondev.png","language":"Haskell","readme":"## About\n\nThis is a library that facilitates sending email via AWS SES using the\nbackground processor [hworker](http://hackage.haskell.org/package/hworker). In\nparticular, it handles rate limiting (for sending rate currently, not\ndaily quotas), as SES does not queue messages.\n\n## Rate limiting\n\nAside from sending emails in the background, the main thing that\n`hworker-ses` provides is rate limiting. The rate limiting is only on\na per-process (most likely, per server) basis, as it is controlled via\nin-memory storage. This means that you should take into account how\nmany workers you are likely to have when setting the\nmessages-per-second rate on the workers.\n\nFor example, if your rate limit is 30 messages per second, and you expect\nto have at most 5 workers (you can organize them however you like, but a\nsimple strategy is just to start a worker with each application process),\nthen if you set the rate limit to be 6 messages per second, things will be\nfine.\n\nNote that if you do run over, it won't mean that your messages actually\ndon't get delivered. That error code will trigger a retry on the message,\nso eventually it will go out. But it's wasteful (as you can know in advance\nif a given message will actually be able to be sent), and if you really\nmess it up (ie, set an absurdly high limit), you potentially will have\nyour API calls rate limited, which isn't good.\n\n## Usage\n\nThe program in the `example` directory is probably most of what you\nneed to get started. In particular, you create an `hworker` (you need\nto give it a name for the queue - this should be shared by any servers\nthat should be accessing the same queue and sending the same messages,\nthough if you are sharing the redis server with other applications,\nthis should be distinct).  The third argument is the per-second rate\nlimit for this server, and the last argument is the address that the\nmessages are sent from.\n\nUsing what you get back, you can spawn workers and a monitor. Then you\ncan queue as many messages as you want, and they will be sent out by\nthe workers.\n\nYou need to start at least one worker thread and at least\none monitor thread. You can have as many of these as you want, though\ngenerally speaking, having more than one monitor thread per server is\nprobably overkill (for the system to work, you want at least one\nmonitor running _somewhere_ - so if a whole server crashes, you want\nthere to be a monitor elsewhere). Having many workers makes things run\nfaster. In particular, if you have a high sending limit, you will\nprobably want several workers.\n\nAs specified in the [hworker](http://hackage.haskell.org/package/hworker)\ndocumentation, the semantics of this queue is at-least-once, so it's\npossible that messages can get sent multiple times in error conditions\n(like if an entire server crashes right after the message is sent, but\nbefore the fact that it was sent is acknowledged). But, provided that\nredis is still available and is reliable, messages that have been\nqueued are guaranteed to get sent eventually (even in the case of\nservers crashing, etc). The only caveat to that is that for the\nmessage to get sent at least one worker and one monitor thread must be\nrunning (thoses don't need to be running all the time, but as long as\nthey aren't running, messages might be delayed. Once they're started again,\nthose delayed messages will go out).\n\n## Primary Libraries Used\n\n- hworker\n- amazonka-ses\n\n## Contributors\n\n- Daniel Patterson \u003cdbp@dbpmail.net\u003e\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpositiondev%2Fhworker-ses","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpositiondev%2Fhworker-ses","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpositiondev%2Fhworker-ses/lists"}