{"id":13413241,"url":"https://github.com/bamzi/jobrunner","last_synced_at":"2025-04-08T11:12:34.555Z","repository":{"id":49369965,"uuid":"44652241","full_name":"bamzi/jobrunner","owner":"bamzi","description":"Framework for performing work asynchronously, outside of the request flow","archived":false,"fork":false,"pushed_at":"2020-11-14T21:03:29.000Z","size":75,"stargazers_count":1069,"open_issues_count":11,"forks_count":98,"subscribers_count":27,"default_branch":"master","last_synced_at":"2025-04-01T10:07:13.036Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bamzi.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":"2015-10-21T04:17:01.000Z","updated_at":"2025-03-31T14:59:14.000Z","dependencies_parsed_at":"2022-08-25T20:21:30.624Z","dependency_job_id":null,"html_url":"https://github.com/bamzi/jobrunner","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/bamzi%2Fjobrunner","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bamzi%2Fjobrunner/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bamzi%2Fjobrunner/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bamzi%2Fjobrunner/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bamzi","download_url":"https://codeload.github.com/bamzi/jobrunner/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247829511,"owners_count":21002997,"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-07-30T20:01:35.892Z","updated_at":"2025-04-08T11:12:34.537Z","avatar_url":"https://github.com/bamzi.png","language":"Go","funding_links":[],"categories":["Job Scheduler","开源类库","Utilities","Go","Open source library","作业调度","Relational Databases","工具库","作业调度器","实用工具","實用工具"],"sub_categories":["Search and Analytic Databases","任务/定时器","Advanced Console UIs","Task/Timer","HTTP Clients","SQL 查询语句构建库","交流","检索及分析资料库","高级控制台界面","高級控制台界面","\u003cspan id=\"高级控制台用户界面-advanced-console-uis\"\u003e高级控制台用户界面 Advanced Console UIs\u003c/span\u003e"],"readme":"# ![](https://raw.githubusercontent.com/bamzi/jobrunner/master/views/runclock.jpg) JobRunner\n\nJobRunner is framework for performing work asynchronously, outside of the request flow. It comes with cron to schedule and queue job functions for processing at specified time. \n\nIt includes a live monitoring of current schedule and state of active jobs that can be outputed as JSON or Html template. \n\n## Install\n\n`go get github.com/bamzi/jobrunner`\n\n### Setup\n\n```go\npackage main\n\nimport \"github.com/bamzi/jobrunner\"\n\nfunc main() {\n    jobrunner.Start() // optional: jobrunner.Start(pool int, concurrent int) (10, 1)\n    jobrunner.Schedule(\"@every 5s\", ReminderEmails{})\n}\n\n// Job Specific Functions\ntype ReminderEmails struct {\n    // filtered\n}\n\n// ReminderEmails.Run() will get triggered automatically.\nfunc (e ReminderEmails) Run() {\n    // Queries the DB\n    // Sends some email\n    fmt.Printf(\"Every 5 sec send reminder emails \\n\")\n}\n```\n\n### Live Monitoring\n![](https://raw.githubusercontent.com/bamzi/jobrunner/master/views/jobrunner-html.png)\n```go\n\n// Example of GIN micro framework\nfunc main() {\n    routes := gin.Default()\n\n    // Resource to return the JSON data\n    routes.GET(\"/jobrunner/json\", JobJson)\n\n    // Load template file location relative to the current working directory\n    routes.LoadHTMLGlob(\"../github.com/bamzi/jobrunner/views/Status.html\")\n\n    // Returns html page at given endpoint based on the loaded\n    // template from above\n    routes.GET(\"/jobrunner/html\", JobHtml)\n\n    routes.Run(\":8080\")\n}\n\nfunc JobJson(c *gin.Context) {\n    // returns a map[string]interface{} that can be marshalled as JSON\n    c.JSON(200, jobrunner.StatusJson())\n}\n\nfunc JobHtml(c *gin.Context) {\n    // Returns the template data pre-parsed\n    c.HTML(200, \"\", jobrunner.StatusPage())\n\n}\n\n```\n## WHY?\nTo reduce our http response latency by 200+%\n\nJobRunner was created to help us process functions unrelated to response without any delays to the http response. GoRoutines would timeout because response has already been processed, closing the instance window all together. \n\nInstead of creating a separate independent app, we wanted to save time and manageability of our current app by coupling-in the job processing. We did not want to have micro services. It's premature optimization.\n\nIf you have a web app or api service backend and want a job processing framework built into your app then JobRunner is for you. Once you hit mass growth and need to scale, you can simply decouple you JobRunners into a dedicated app.\n\n## Use cases\nHere are some examples of what we use JobRunner for:\n\n* Send emails to new users after signup\n* Sending push notification or emails based on specifics\n* ReMarketing Engine - send invites, reminder emails, etc ...\n* Clean DB, data or AMZ S3\n* Sending Server stats to monitoring apps\n* Send data stats at daily or weekly intervals\n\n### Supported Featured\n*All jobs are processed outside of the request flow*\n\n* Now: process a job immediately\n* In: processing a job one time, after a given time\n* Every: process a recurring job after every given time gap\n* Schedule: process a job (recurring or otherwise) at a given time\n\n\n## Compatibility\n\nJobRunner is designed to be framework agnostic. So it will work with pure Go apps as well as any framework written in Go Language. \n\n*Verified Supported Frameworks*\n\n* Gin\n* Echo\n* Martini\n* Beego\n* Revel (JobRunner is modified version of revel's Jobs module)\n* ...\n\n**Examples \u0026 recipes are coming soon**\n\n## Basics\n\n```go\n    jobrunner.Schedule(\"* */5 * * * *\", DoSomething{}) // every 5min do something\n    jobrunner.Schedule(\"@every 1h30m10s\", ReminderEmails{})\n    jobrunner.Schedule(\"@midnight\", DataStats{}) // every midnight do this..\n    jobrunner.Every(16*time.Minute, CleanS3{}) // evey 16 min clean...\n    jobrunner.In(10*time.Second, WelcomeEmail{}) // one time job. starts after 10sec\n    jobrunner.Now(NowDo{}) // do the job as soon as it's triggered\n```\n[**More Detailed CRON Specs**](https://github.com/robfig/cron/blob/v2/doc.go)\n\n## Contribute\n\n**Use issues for everything**\n\n- Report problems\n- Discuss before sending pull request\n- Suggest new features\n- Improve/fix documentation\n\n## Credits\n- [revel jobs module](https://github.com/revel/modules/tree/master/jobs) - Origin of JobRunner\n- [robfig cron v3](https://github.com/robfig/cron/tree/v3) - github.com/robfig/cron/v3\n- [contributors](https://github.com/bamzi/jobrunner/graphs/contributors)\n\n### Author \n**Bam Azizi**\nGithub: [@bamzi](https://github.com/bamzi)\nTwitter: [@bamazizi](https://twitter/bamazizi)\n\n#### License\nMIT","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbamzi%2Fjobrunner","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbamzi%2Fjobrunner","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbamzi%2Fjobrunner/lists"}