{"id":43506890,"url":"https://github.com/susamn/rio","last_synced_at":"2026-02-03T12:37:48.359Z","repository":{"id":57524828,"uuid":"253399163","full_name":"susamn/rio","owner":"susamn","description":"A lightweight job scheduler based on priority queue with timeout, retry, replica, context cancellation and easy semantics for job chaining. Build for golang web apps.","archived":false,"fork":false,"pushed_at":"2020-05-14T05:01:08.000Z","size":86,"stargazers_count":61,"open_issues_count":8,"forks_count":6,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-06-20T13:40:27.693Z","etag":null,"topics":["chaining","chaining-callables","chaining-middleware-in-go","go","golang","goroutine","heap","job","load-balancer","minheap","priority-queue","scheduler","scheduling","worker"],"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/susamn.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-04-06T05:00:25.000Z","updated_at":"2024-05-05T15:07:46.000Z","dependencies_parsed_at":"2022-08-26T04:00:59.898Z","dependency_job_id":null,"html_url":"https://github.com/susamn/rio","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/susamn/rio","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/susamn%2Frio","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/susamn%2Frio/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/susamn%2Frio/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/susamn%2Frio/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/susamn","download_url":"https://codeload.github.com/susamn/rio/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/susamn%2Frio/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29046103,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-03T10:09:22.136Z","status":"ssl_error","status_checked_at":"2026-02-03T10:09:16.814Z","response_time":96,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["chaining","chaining-callables","chaining-middleware-in-go","go","golang","goroutine","heap","job","load-balancer","minheap","priority-queue","scheduler","scheduling","worker"],"created_at":"2026-02-03T12:37:44.810Z","updated_at":"2026-02-03T12:37:48.352Z","avatar_url":"https://github.com/susamn.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Table of Contents\n\n1.  [Introduction](#org8f950e8)\n    1.  [What is RIO?](#org64d7944)\n    2.  [Concern](#org23a1e51)\n        1.  [An asynchronous job processor](#orgf7dc6c9)\n        2.  [Easy management of these goroutines and chaining them](#orgc2a657c)\n\n\n\u003ca id=\"org8f950e8\"\u003e\u003c/a\u003e\n\n# Introduction\n\n\n![Tag](https://img.shields.io/github/v/tag/susamn/rio) ![Go Build](https://github.com/susamn/rio/workflows/Go/badge.svg) [![Coverage](https://codecov.io/gh/susamn/rio/branch/master/graph/badge.svg)](https://codecov.io/gh/susamn/rio) ![license](https://img.shields.io/github/license/susamn/rio) [![godoc](https://img.shields.io/badge/godoc-reference-blue)](https://pkg.go.dev/github.com/susamn/rio?tab=doc)\n\n[![Go Report Card](https://goreportcard.com/badge/github.com/susamn/rio)](https://goreportcard.com/report/github.com/susamn/rio) [![Code Inspector Badge](https://www.code-inspector.com/project/5768/status/svg)](https://www.code-inspector.com/project/5768/status/svg) [![Code Inspector Report Card](https://www.code-inspector.com/project/5768/score/svg)](https://www.code-inspector.com/project/5768/score/svg) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/d833f224d9974475a011cb7191cd19e4)](https://app.codacy.com/manual/susamn/rio?utm_source=github.com\u0026utm_medium=referral\u0026utm_content=susamn/rio\u0026utm_campaign=Badge_Grade_Dashboard)\n\n\u003ca id=\"org64d7944\"\u003e\u003c/a\u003e\n\n## What is RIO?\n\nRio is a lightweight job scheduler and job chaining library. Its mainly build for Golang web apps, but it can be very\neasily mold to serve any application needing job scheduling. The library is an  asynchronous job processor, which makes\nall the backend calls asynchronously with retry, timeout and context cancellation functionality. It also provides very\neasy semantics to join multiple datasources based on their output and input types, at the same time having no coupling\nbetween the datasources. This helps in creating new apis or resolvers for GraphQL apis a breeze.\n\n\n\u003ca id=\"org23a1e51\"\u003e\u003c/a\u003e\n\n## Concern\n\nMany times we write web apps which connects to different data sources, combines the data obtained from these sources and\nthen do some more jobs. During these process, we do a lot of boilerplate to transform one data type to other. Also in the\nabsense of a proper job scheduler, we create goroutines abruptly and without proper management. These create unmanagable\ncode. To update those code is even more hard in future, when there is a new team member in the team.\n\nRio tries to solve this problem by introducing two concepts.\n\n\n\u003ca id=\"orgf7dc6c9\"\u003e\u003c/a\u003e\n\n### An asynchronous job processor\n\nThis is the piece which runs the multiple jobs asynchronously (Based on the Rob Pike video: Google I/O 2010). It has a\npriority queue(`balancer.go` and `pool.go`) which hands off incoming requests to a set of managed workers. The balancer\nhands off new job to the lightly loaded worker.\n\n\n\u003ca id=\"orgc2a657c\"\u003e\u003c/a\u003e\n\n### Easy management of these goroutines and chaining them\n\nHow many times do we do this:\n\n    call service 1 in goroutine 1\n    wait and get response from goroutine 1\n    call service 2 in goroutine 2, taking piece of data from service call 1\n    wait and get response from goroutine 2\n    call service 3 in goroutine 3, taking piece of data from service call 3\n    wait and get response from goroutine 3\n\nYou get the idea, this only delays thing more and does a lot of context switching. Rio helps in this, by chaining multiple\ncalls together by means of using closures and function types and runs in one goroutine.\n\nNow many can think is it not going to be slower compared to doing multiple goroutine calls. I think not, it will be faster.\nThink of the previous example. If you do not get response from service 1, can you invoke service 2, or if service 2 fails,\ncan you call service 3? No right, as there is data dependency between these calls.\n\nRio chains dependent jobs together by introducing this pattern.\n\n    request := context,\n              (\u003ccallback of service 1\u003e.WithTimeOut(100 ms).WithRetry(3))\n              .FollowedBy(\u003cfunction which can transform data from service 1 response to request or partial request of 2\u003e,\n                          \u003ccallback of service 2\u003e)\n              .FollowedBy(\u003cfunction which can transform data from service 2 response to request or partial request of 3\u003e,\n                                      \u003ccallback of service 3\u003e)\n\nIn the example in `examples/web.go` the chaining pattern looks like this:\n\n    request := rio.BuildRequests(context.Background(),\n          rio.NewFutureTask(callback1).WithMilliSecondTimeout(10).WithRetry(3), 2).\n          FollowedBy(Call1ToCall2, rio.NewFutureTask(callback2).WithMilliSecondTimeout(20))\n\nOnce the chaining is done, post the job to load balancer\n\n    balancer.PostJob(request)\n    \u003c-request.CompletedChannel\n\nOnce the call chain happens, the request comes back with responses for all these calls in a slice and you can do this\n\n1.  Only one job response\n\n        request.GetOnlyResponse()\n\n    or\n\n2.  Multiple job response\n\n        request.GetResponse(index) ---0,1,2\n\n    If any job fails, the response will be empty response, specifically `rio.EMPTY_CALLBACK_RESPONSE`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsusamn%2Frio","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsusamn%2Frio","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsusamn%2Frio/lists"}