{"id":22353710,"url":"https://github.com/rosberry/go-scheduler","last_synced_at":"2025-03-26T12:27:48.811Z","repository":{"id":64297284,"uuid":"311279171","full_name":"rosberry/go-scheduler","owner":"rosberry","description":"Library to handle scheduled tasks","archived":false,"fork":false,"pushed_at":"2022-10-19T09:45:41.000Z","size":75,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-31T13:42:56.268Z","etag":null,"topics":["golang","library"],"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/rosberry.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":"2020-11-09T08:59:58.000Z","updated_at":"2022-10-19T09:46:35.000Z","dependencies_parsed_at":"2023-01-15T08:45:47.470Z","dependency_job_id":null,"html_url":"https://github.com/rosberry/go-scheduler","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rosberry%2Fgo-scheduler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rosberry%2Fgo-scheduler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rosberry%2Fgo-scheduler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rosberry%2Fgo-scheduler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rosberry","download_url":"https://codeload.github.com/rosberry/go-scheduler/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245652684,"owners_count":20650538,"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":["golang","library"],"created_at":"2024-12-04T13:09:32.982Z","updated_at":"2025-03-26T12:27:48.785Z","avatar_url":"https://github.com/rosberry.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Scheduler ![https://img.shields.io/badge/golang-1.15-blue](https://img.shields.io/badge/golang-1.15-blue)\n\nThis is a library to handle scheduled tasks.\nThe task list is stored in the database (GORM).\n\n## Base usage\n\n1. Import the library.\n\n```golang\nimport \"github.com/rosberry/go-scheduler\"\n```\n2. Use `gorm` ORM library to work with the database in the scheduler. You make use structure `scheduler.Task` for create migration.\n```golang\ntx := db.Begin()\ntx.Migrator().AutoMigrate(\u0026scheduler.Task{})\n```\n\n3. Initialize the scheduler with 3 arguments: `gorm db`, `taskFuncMap`, `sleepDuration`.\u003cbr\u003e \n`gorm db`: instance `*gorm.DB` in gorm library.\u003cbr\u003e\n`taskFuncMap`: Before adding argument we should create schedule function(s) and add them to the special map `scheduler.TaskFuncsMap`. Each function must return 2 parameters. The first is the status after the completion of the task. Possible options: `TaskStatusDone`, `TaskStatusWait`, `TaskStatusDeferred`. The second is how long it will take to call this task again. The passed types can be: `time.Duration`, `time.Time` or `nil`. If the time was not transmitted (nil was used), then we will use the static values stored in the database for this task. More on this later.\u003cbr\u003e\n`sleepDuration`: time interval between checking tasks. By default it is 30 seconds and can be set up no less than this value.\n```golang\nprintFunc := func(args scheduler.FuncArgs) (scheduler.TaskStatus, interface{}) {\n\tlog.Print(\"Hello scheduler!\")\n\tnextStart := time.Now().Add(time.Minute * 1)\n\n\treturn scheduler.TaskStatusWait, nextStart\n}\n\nsch := scheduler.New(\n\tdb, // gorm db\n\t\u0026scheduler.TaskFuncsMap{\n\t\t\"print\": printFunc,\n\t}, \n\ttime.Minute * 5, // sleep duration\n)\n\ngo sch.Run()\n```\n\n## Additional usage\nYou can add a static interval for the execution of tasks. If a time is specified for a task, then it will be singleton.\n\n```golang\ntaskPlan := scheduler.TaskPlan{\n\t\"print\": 5, // 5 minutes\n}\nsch.Configure(taskPlan)\n// ...\ngo sch.Run()\n```\n\nYou can add a dynamic tasks adding code after running scheduler.\n\n```golang\ngo sch.Run()\n// ...\nsch.Add(\n\t\"upd_print\", // alias\n\t\"upd_print_1\", // current name\n\tscheduler.FuncArgs{ \"name\": \"Ivan\" }, // arguments\n\ttime.Now().Add(time.Second*10), // runAt\n\t5, // interval in minutes\n)\n```\n\nYou can simple inintialize scheduler with singleton and arguments:\n```golang\nsch, err := scheduler.NewWithConfig(scheduler.Config{\n\tDb:    db,\n\tJobs: scheduler.TaskSettings{\n\t\ttestObj.Alias: {\n\t\t\tInterval: 5, // 5 minutes\n\t\t\tFunc:     printFunc, // job func\n\t\t\tArgs: scheduler.FuncArgs{\n\t\t\t\t\"name\": \"print\",\n\t\t\t},\n\t\t},\n\t},\n\tSleep: scheduler.MinimalSleepDuration,\n})\n// ...\ngo sch.Run()\n```\n\nYou can create your task model for scheduler migration. To do this, make sure your structure meets the minimum requirements of the basic scheduler structure:\n```golang\ntype Task struct {\n    ID    uint `gorm:\"primary_key\"`\n    Alias string\n\n    Name       string\n    Arguments  string\n    Singleton bool\n\n    Status      TaskStatus\n    Schedule    uint\n    ScheduledAt time.Time\n\n    CreatedAt time.Time\n    UpdatedAt time.Time\n}\n```\n\n## Full example:\n```golang\npackage main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"time\"\n\n\tscheduler \"github.com/rosberry/go-schedule\"\n\t\"gorm.io/driver/postgres\"\n\t\"gorm.io/gorm\"\n)\n\nconst (\n\tsleepDuration           = time.Minute\n\tupdPrintScheduleTimeout = 5\n)\n\nfunc main() {\n\t// Connect to DB\n\tconnString := \"host=localhost port=5432 user=postgres dbname=clapper password=123 sslmode=disable\"\n\n\tdb, err := gorm.Open(postgres.Open(connString), \u0026gorm.Config{})\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\t// Create FuncsMap and add our TaskFunc's\n\ttaskFuncsMap := scheduler.TaskFuncsMap{\n\t\t\"upd_print\":     PrintJobSingleton,\n\t\t\"upd_printName\": PrintWithArgs,\n\t}\n\n\t// Init TaskPlan for Singleton functions\n\ttaskPlan := scheduler.TaskPlan{\n\t\t\"upd_print\": updPrintScheduleTimeout,\n\t}\n\n\t// Init scheduler\n\tsch := scheduler.New(db, \u0026taskFuncsMap, sleepDuration) // gorm db in first func argument\n\n\t// Add to DB and configure singleton tasks\n\tsch.Configure(taskPlan)\n\n\t// Run scheduler\n\tgo sch.Run()\n\n\tfor i := 0; i \u003c 3; i++ {\n\t\tsch.Add(\n\t\t\t\"upd_printName\",\n\t\t\tfmt.Sprintf(\"upd_printName #%v\", i),\n\t\t\tscheduler.FuncArgs{\"name\": fmt.Sprintf(\"Ivan %v\", i)},\n\t\t\ttime.Now().Add(time.Second*10),\n\t\t\t0,\n\t\t)\n\t\ttime.Sleep(time.Second * 3)\n\t}\n\n\t// Stub\n\ttime.Sleep(time.Hour)\n\tlog.Println(\"exit\")\n}\n\n// Create schedule TaskFunc's\n// PrintJobSingleton ...\nfunc PrintJobSingleton(args scheduler.FuncArgs) (status scheduler.TaskStatus, when interface{}) {\n\tlog.Println(\"PrintJobSingleton:\", time.Now())\n\n\treturn scheduler.TaskStatusWait, time.Now().Add(time.Minute * 1)\n}\n\n// PrintWithArgs ...\nfunc PrintWithArgs(args scheduler.FuncArgs) (status scheduler.TaskStatus, when interface{}) {\n\tif name, ok := args[\"name\"]; ok {\n\t\tlog.Println(\"PrintWithArgs:\", time.Now(), name)\n\t\treturn scheduler.TaskStatusWait, time.Now().Add(time.Minute * 1)\n\t}\n\n\tlog.Print(\"Not found name arg in func args\")\n\n\treturn scheduler.TaskStatusDeferred, time.Now().Add(time.Minute * 1)\n}\n```\n\n# Task types\n\n- Singleton - unique task, can be only one task with alias in DB.\n- Not singleton - dynamic task, that can be created while the program is running, supports arguments, there can be several tasks in the database with one alias.\n\n# Roadmap\n\n- [x] Scheduled tasks\n- [x] Once tasks\n- [x] Concurency\n- [x] Transactions\n- [ ] Configure tasks\n- [ ] ...\n\n## About\n\n\u003cimg src=\"https://github.com/rosberry/Foundation/blob/master/Assets/full_logo.png?raw=true\" height=\"100\" /\u003e\n\nThis project is owned and maintained by [Rosberry](http://rosberry.com). We build mobile apps for users worldwide 🌏.\n\nCheck out our [open source projects](https://github.com/rosberry), read [our blog](https://medium.com/@Rosberry) or give us a high-five on 🐦 [@rosberryapps](http://twitter.com/RosberryApps).\n\n## License\n\nThis project is available under the MIT license. See the LICENSE file for more info.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frosberry%2Fgo-scheduler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frosberry%2Fgo-scheduler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frosberry%2Fgo-scheduler/lists"}