Framework for performing work asynchronously, outside of the request flow

JobRunner

JobRunner 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.

It includes a live monitoring of current schedule and state of active jobs that can be outputed as JSON or Html template.

Install

go get github.com/bamzi/jobrunner

Setup

package main

import "github.com/bamzi/jobrunner"

func main() {
    jobrunner.Start() // optional: jobrunner.Start(pool int, concurrent int) (10, 1)
    jobrunner.Schedule("@every 5s", ReminderEmails{})
}

// Job Specific Functions
type ReminderEmails struct {
    // filtered
}

// ReminderEmails.Run() will get triggered automatically.
func (e ReminderEmails) Run() {
    // Queries the DB
    // Sends some email
    fmt.Printf("Every 5 sec send reminder emails \n")
}

Live Monitoring

// Example of GIN micro framework
func main() {
    routes := gin.Default()

    // Resource to return the JSON data
    routes.GET("/jobrunner/json", JobJson)

    // Load template file location relative to the current working directory
    routes.LoadHTMLGlob("../github.com/bamzi/jobrunner/views/Status.html")

    // Returns html page at given endpoint based on the loaded
    // template from above
    routes.GET("/jobrunner/html", JobHtml)

    routes.Run(":8080")
}

func JobJson(c *gin.Context) {
    // returns a map[string]interface{} that can be marshalled as JSON
    c.JSON(200, jobrunner.StatusJson())
}

func JobHtml(c *gin.Context) {
    // Returns the template data pre-parsed
    c.HTML(200, "", jobrunner.StatusPage())

}

WHY?

To reduce our http response latency by 200+%

JobRunner 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.

Instead 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.

If 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.

Use cases

Here are some examples of what we use JobRunner for:

  • Send emails to new users after signup
  • Sending push notification or emails based on specifics
  • ReMarketing Engine - send invites, reminder emails, etc ...
  • Clean DB, data or AMZ S3
  • Sending Server stats to monitoring apps
  • Send data stats at daily or weekly intervals

Supported Featured

All jobs are processed outside of the request flow

  • Now: process a job immediately
  • In: processing a job one time, after a given time
  • Every: process a recurring job after every given time gap
  • Schedule: process a job (recurring or otherwise) at a given time

Compatibility

JobRunner is designed to be framework agnostic. So it will work with pure Go apps as well as any framework written in Go Language.

Verified Supported Frameworks

  • Gin
  • Echo
  • Martini
  • Beego
  • Revel (JobRunner is modified version of revel's Jobs module)
  • ...

Examples & recipes are coming soon

Basics

    jobrunner.Schedule("* */5 * * * *", DoSomething{}) // every 5min do something
    jobrunner.Schedule("@every 1h30m10s", ReminderEmails{})
    jobrunner.Schedule("@midnight", DataStats{}) // every midnight do this..
    jobrunner.Every(16*time.Minute, CleanS3{}) // evey 16 min clean...
    jobrunner.In(10*time.Second, WelcomeEmail{}) // one time job. starts after 10sec
    jobrunner.Now(NowDo{}) // do the job as soon as it's triggered

More Detailed CRON Specs

Contribute

Use issues for everything

  • Report problems
  • Discuss before sending pull request
  • Suggest new features
  • Improve/fix documentation

Credits

Author

Bam Azizi Github: @bamzi Twitter: @bamazizi

License

MIT

Comments
  • Help with Dep

    Help with Dep

    First of all wanted to chime in and say that jobrunner is fantastic and I've been using it for some time now. Recently I seem to be having issues with trying to install the dependencies with dep after the v3 upgrade from cron

    dep:
     version     : v0.5.4
     build date  : 2019-07-01
     git hash    : 1f7c19e
     go version  : go1.12.6
     go compiler : gc
     platform    : darwin/amd64
     features    : ImportDuringSolve=false
    
    [[constraint]]
      branch = "master"
      name = "github.com/bamzi/jobrunner"
    
    [[constraint]]
      branch = "master"
      name = "github.com/asaskevich/EventBus"
    
    [[constraint]]
      branch = "master"
      name = "github.com/docker/docker"
    
    [[constraint]]
      name = "github.com/enriquebris/goconcurrentqueue"
      version = "0.1.0"
    
    [[constraint]]
      name = "github.com/fsnotify/fsnotify"
      version = "1.4.7"
    
    [[constraint]]
      name = "github.com/labstack/echo"
      version = "3.3.10"
    
    [[constraint]]
      name = "github.com/satori/go.uuid"
      version = "1.2.0"
    
    [[constraint]]
      name = "github.com/sirupsen/logrus"
      version = "1.4.1"
    
    [[constraint]]
      name = "github.com/spf13/viper"
      version = "1.4.0"
    
    [[constraint]]
      branch = "master"
      name = "golang.org/x/net"
    
    [[constraint]]
      name = "gopkg.in/resty.v1"
      version = "1.12.0"
    
    [prune]
      go-tests = true
      unused-packages = true
    

    On a clean install, so nothing in vendor and nothing in pkg/dep directory getting the following error when I run

    dep ensure -v

    Solving failure: No versions of github.com/robfig/cron met constraints:
    	v3.0.0: Could not introduce github.com/robfig/[email protected], as its subpackage github.com/robfig/cron/v3 is missing. Package is required by:
    	(root)
    	github.com/bamzi/jobrunner@master
    	v1.2.0: Could not introduce github.com/robfig/[email protected], as its subpackage github.com/robfig/cron/v3 is missing. Package is required by:
    	(root)
    	github.com/bamzi/jobrunner@master
    	v1.1.0: Could not introduce github.com/robfig/[email protected], as its subpackage github.com/robfig/cron/v3 is missing. Package is required by:
    	(root)
    	github.com/bamzi/jobrunner@master
    	v1.0.0: Could not introduce github.com/robfig/[email protected], as its subpackage github.com/robfig/cron/v3 is missing. Package is required by:
    	(root)
    	github.com/bamzi/jobrunner@master
    	v3.0.0-rc1: Could not introduce github.com/robfig/[email protected], as its subpackage github.com/robfig/cron/v3 is missing. Package is required by:
    	(root)
    	github.com/bamzi/jobrunner@master
    	master: Could not introduce github.com/robfig/cron@master, as its subpackage github.com/robfig/cron/v3 is missing. Package is required by:
    	(root)
    	github.com/bamzi/jobrunner@master
    	v1: Could not introduce github.com/robfig/cron@v1, as its subpackage github.com/robfig/cron/v3 is missing. Package is required by:
    	(root)
    	github.com/bamzi/jobrunner@master
    	v2: Could not introduce github.com/robfig/cron@v2, as its subpackage github.com/robfig/cron/v3 is missing. Package is required by:
    	(root)
    	github.com/bamzi/jobrunner@master
    	v3: Could not introduce github.com/robfig/cron@v3, as its subpackage github.com/robfig/cron/v3 is missing. Package is required by:
    	(root)
    	github.com/bamzi/jobrunner@master
    	v3-dev: Could not introduce github.com/robfig/cron@v3-dev, as its subpackage github.com/robfig/cron/v3 is missing. Package is required by:
    	(root)
    	github.com/bamzi/jobrunner@master
    

    All the imports in the code reference

    import (
    "github.com/bamzi/jobrunner"
    "github.com/robfig/cron/v3"
    )
    
    

    Any help is very much appreciated and thank you

  • cannot find package

    cannot find package "github.com/robfig/cron/v3"

    When we want to build our code after go get -vwe get this following error. There is no package such as "github.com/robfig/cron/v3"

    github.com/robfig/cron (download) package github.com/robfig/cron/v3: cannot find package "github.com/robfig/cron/v3" in any of: /usr/local/go/src/github.com/robfig/cron/v3 (from $GOROOT) /go/src/github.com/robfig/cron/v3 (from $GOPATH)

  • use Gin context inside job function

    use Gin context inside job function

    I'm trying to implement jobrunner in my Gin-gonic framework and it works.

    Problem is when i want to use gin context inside the function

    jobrunner.Start() // optional: jobrunner.Start(pool int, concurrent int) (10, 1)
    jobrunner.Schedule("@every 20s", CheckExpiredUrl{})
    

    // Job Specific Functions type CheckExpiredUrl struct { // filtered }

    func (e CheckExpiredUrl) Run() { // Queries the DB fmt.Println("Every 20 sec Check Expired Url") db := c.MustGet("db").(*mgo.Database) urls := []models.Url{} err := db.C(models.CollectionUrl).Find(nil).Sort("-expired_at").All(&urls) if err != nil { c.Error(err) } // do something with database } `

    I need to use c *gin.Context

    inside jobrunner function, and how to do that?

  • change job execution state

    change job execution state

    We have a case want to stop scheduled jobs temporarily.

    It's ok to kepp state on memory. We setup schedule with execution state, and change enable/disable on statusPage.

  • Name not displayed in status page even when explicitly set

    Name not displayed in status page even when explicitly set

    I am currently trying to use jobrunner to setup scheduled pulls of data, I want to set the name of the job based on what is being pulled by that job explicitly. Below is a breakdown of my code and the json that I get back when checking the status:

    func (ud *UserData) Schedule(interval time.Duration, jobName string) {
    	regenerate_data := jobrunner.New(ud)
    	regenerate_data.Name = "Test"
    	ud.job = regenerate_data
    	jobrunner.Every(interval, regenerate_data)
    	// Initial run
    	jobrunner.Now(regenerate_data)
    }
    
    {
        "jobrunner": [
            {
                "Id": 1,
                "JobRunner": {
                    "Name": "",
                    "Status": "IDLE",
                    "Latency": "157.331µs"
                },
                "Next": "2017-09-01T11:28:38-07:00",
                "Prev": "2017-09-01T11:27:38-07:00"
            }
        ]
    }
    

    I'd expect that the name is displayed no matter what. For testing purposes I had the job log out the name and verify that the job has it set properly:

    func (ud *UserData) Run() {
    	log.Debugf("Starting job %s", ud.job.Name)
    	log.Info(ud.job.Name)
    	return
    }
    

    Which gave me this log output showing that the name is in fact set:

    {"level":"info","msg":"Test","time":"2017-09-01T11:26:38.957340798-07:00"}
    {"level":"info","msg":"Test","time":"2017-09-01T11:27:38.000367709-07:00"}
    
  • Proposal: Save state on exit

    Proposal: Save state on exit

    It would be great if package optionally save state (as a .gob or .json files for example) on os interrupt signals. And restore it when run again. You can set path to save state files as a third parameter in .Start(). If it set, saving will be active.

  • Job runner quits after start

    Job runner quits after start

    I'm trying to run jobrunner but it quits right after start:

    package main
    
    import (
        "fmt"
        "github.com/bamzi/jobrunner"
    )
    
    func main() {
        jobrunner.Start(10, 1)
        jobrunner.Schedule("@every 5s", ReminderEmails{})
    }
    
    type ReminderEmails struct {
    }
    
    func (e ReminderEmails) Run() {
        fmt.Printf("Every 5 sec send reminder emails \n")
    }
    

    Output:

    ❯ go run app.go
    [JobRunner] 2015/10/30 - 09:48:06 Started...  
    
    ❯ 
    
    

    Go version

    go version go1.5.1 linux/amd64
    
  • Refractor the start function.

    Refractor the start function.

    The start function applies a very basic approach in reading the parameters, it can be cleaned and made scalable if in future other params are added to the function signature.

    I shall like to contribute to the task.

  • Job run multi times after stop -> start

    Job run multi times after stop -> start

    So my case is when i stop the job:

            entries := jobrunner.StatusPage()
    	for _, e := range entries {
    		if e.JobRunner.Name == task.ID.Hex() {
    			gocore.Log().Info().Str("id", task.ID.Hex()).Str("desc", task.Description).Msg("Stopped task")
    			jobrunner.Remove(e.Id)
    			break
    		}
    	}
    

    and add it back after a time

                    job := jobrunner.New(SendNotification{
    			Title: jsoniter.Get(rawData, "title").ToString(),
    			Message: jsoniter.Get(rawData, "message").ToString(),
    		})
    		job.Name = task.ID.Hex()
    		sched, err := cron.Parse(task.CronExpression)
    		if err != nil {
    			gocore.Log().Error().Err(err).Msg("Error when run schedule task data")
    			return
    		}
    		jobrunner.MainCron.Schedule(sched, job)
    

    this job run multi time before it actualy going correct depend on how long i stop the task

    here is details log:

    2019-08-07T11:42:22+07:00 DBG D:/Works/Radiant/Tokkor_server/sub_admin/backend/src/HandleScheduler.go:256 > Error when decode schedule task data msg="With a message here" title="Cool title "
    2019-08-07T11:42:22+07:00 DBG D:/Works/Radiant/Tokkor_server/sub_admin/backend/src/HandleScheduler.go:256 > Error when decode schedule task data msg="With a message here" title="Cool title "
    2019-08-07T11:42:22+07:00 DBG D:/Works/Radiant/Tokkor_server/sub_admin/backend/src/HandleScheduler.go:256 > Error when decode schedule task data msg="With a message here" title="Cool title "
    2019-08-07T11:42:22+07:00 DBG D:/Works/Radiant/Tokkor_server/sub_admin/backend/src/HandleScheduler.go:256 > Error when decode schedule task data msg="With a message here" title="Cool title "
    2019-08-07T11:42:22+07:00 DBG D:/Works/Radiant/Tokkor_server/sub_admin/backend/src/HandleScheduler.go:256 > Error when decode schedule task data msg="With a message here" title="Cool title "
    2019-08-07T11:42:22+07:00 DBG D:/Works/Radiant/Tokkor_server/sub_admin/backend/src/HandleScheduler.go:256 > Error when decode schedule task data msg="With a message here" title="Cool title "
    2019-08-07T11:42:22+07:00 DBG D:/Works/Radiant/Tokkor_server/gocore/HandlerInterface.go:62 > Response: {"code":1,"data":{"rows":[{"id":"5d4a52c60c25a02b04e61c70","description":"This is a test every 5 seconds","data":"{\"type\":1,\"title\":\"Cool title \",\"message\":\"With a message here\"}","cron":"0/5 * * * * ?","enable":true,"created_date":"2019-08-07T04:25:42.514Z"}],"total":1},"msg":"Request success"}
    2019-08-07T11:42:22+07:00 DBG D:/Works/Radiant/Tokkor_server/gocore/AppConfig.go:100 > Post data desc=["ASC"] filter=[""] page=["1"] rows=["8"] sort_by=["null"]
    2019-08-07T11:42:22+07:00 INF Request ip=192.168.1.10 latency=3.9896 method=POST path=/api/v1/scheduler/page status=200 user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.87 Safari/537.36"
    2019-08-07T11:42:25+07:00 DBG D:/Works/Radiant/Tokkor_server/sub_admin/backend/src/HandleScheduler.go:256 > Error when decode schedule task data msg="With a message here" title="Cool title "
    2019-08-07T11:42:30+07:00 DBG D:/Works/Radiant/Tokkor_server/sub_admin/backend/src/HandleScheduler.go:256 > Error when decode schedule task data msg="With a message here" title="Cool title "
    2019-08-07T11:42:35+07:00 DBG D:/Works/Radiant/Tokkor_server/sub_admin/backend/src/HandleScheduler.go:256 > Error when decode schedule task data msg="With a message here" title="Cool title "
    2019-08-07T11:42:37+07:00 INF D:/Works/Radiant/Tokkor_server/sub_admin/backend/src/HandleScheduler.go:243 > Stopped task desc="This is a test every 5 seconds" id=5d4a52c60c25a02b04e61c70```
    
    it run 6 times continuos before actually running correct every 5 seconds
  • option to force job execution?

    option to force job execution?

    Is there any option to force the job execution manually?

    currently im doing something like this

    jobrunner.Start() // optional: jobrunner.Start(pool int, concurrent int) (10, 1)
    jobrunner.Schedule("@every 30s", myJob{})
    
    routes.GET("/jobrunner/force", forceJob)
    
    routes.Run(":8080")
    
    func forceJob(c *gin.Context) {
    
        instances := jobrunner.StatusPage()
    
        for k, _ := range instances {
             job := instances[k].JobRunner
    
             if job.Name == "myJob" {
                 job.Run()
             }
        }
    }
    

    which kinda does what i want: run the job... but it doesn't update the prev and next time when the job should be run... so it's more like a 20% success...

    what i'm looking for is:

    Force the execution of the Job right now... but update the jobrunner to know that the job is running now and it should therefore be run again in (in my example) 30s from the end of the current run.

    what i'm doing at the moment can result in the job getting executed by the jobrunner again while it is still running

  • Getting error on dep ensure -add

    Getting error on dep ensure -add

    Hi I am getting error when I am trying to the add the dependency. Error is

    Fetching sources...

    ensure Solve(): No versions of github.com/robfig/cron met constraints: v3.0.1: Could not introduce github.com/robfig/[email protected], as its subpackage github.com/robfig/cron/v3 is missing. (Package is required by github.com/bamzi/jobrunner@master.) v3.0.0: Could not introduce github.com/robfig/[email protected], as its subpackage github.com/robfig/cron/v3 is missing. (Package is required by github.com/bamzi/jobrunner@master.) v1.2.0: Could not introduce github.com/robfig/[email protected], as its subpackage github.com/robfig/cron/v3 is missing. (Package is required by github.com/bamzi/jobrunner@master.) v1.1.0: Could not introduce github.com/robfig/[email protected], as its subpackage github.com/robfig/cron/v3 is missing. (Package is required by github.com/bamzi/jobrunner@master.) v1.0.0: Could not introduce github.com/robfig/[email protected], as its subpackage github.com/robfig/cron/v3 is missing. (Package is required by github.com/bamzi/jobrunner@master.) v3.0.0-rc1: Could not introduce github.com/robfig/[email protected], as its subpackage github.com/robfig/cron/v3 is missing. (Package is required by github.com/bamzi/jobrunner@master.) master: Could not introduce github.com/robfig/cron@master, as its subpackage github.com/robfig/cron/v3 is missing. (Package is required by github.com/bamzi/jobrunner@master.) v1: Could not introduce github.com/robfig/cron@v1, as its subpackage github.com/robfig/cron/v3 is missing. (Package is required by github.com/bamzi/jobrunner@master.) v2: Could not introduce github.com/robfig/cron@v2, as its subpackage github.com/robfig/cron/v3 is missing. (Package is required by github.com/bamzi/jobrunner@master.) v3: Could not introduce github.com/robfig/cron@v3, as its subpackage github.com/robfig/cron/v3 is missing. (Package is required by github.com/bamzi/jobrunner@master.) v3-dev: Could not introduce github.com/robfig/cron@v3-dev, as its subpackage github.com/robfig/cron/v3 is missing. (Package is required by github.com/bamzi/jobrunner@master.)

  • Still supporting this?

    Still supporting this?

    First of all, thanks for this. It helped me build my own cron job manager. I would still like to use jobrunner for regular internal crons. Are you still supporting it?

  • features: add support in seconds

    features: add support in seconds

    With the example

    jobrunner.Schedule("* */5 * * * *", DoSomething{}) // every 5min do something
    

    But log report err: expected exactly 5 fields, found 6.

    The github.com/robfig/cron/v3 package already support it. So I support add this feature.

    Code change suggest:

    // runjob.go
    func Schedule(spec string, job cron.Job) error {
    	sched, err := cron.ParseStandard(spec)
            // change to 
           // sched, err := cron.Parse(spec)
    	if err != nil {
    		return err
    	}
    	MainCron.Schedule(sched, New(job))
    	return nil
    }
    

    Thanks.

  • runtime error: invalid memory

    runtime error: invalid memory

    I just encountered a runtime error, the logs is as below:

    goroutine 1526 [running]:
    log.(*Logger).Panic(0xc0005440f0, 0xc000467c00, 0x3, 0x3)
            /Users/smy/sdk/go1.13.8/src/log/log.go:212 +0xaa
    github.com/bamzi/jobrunner.(*Job).Run.func1()
            /Users/smy/go/pkg/mod/github.com/bamzi/[email protected]/jobrunner.go:55 +0x1a5
    panic(0xe86880, 0x1804d70)
            /Users/smy/sdk/go1.13.8/src/runtime/panic.go:679 +0x1b2
    main.UpdateNews.Run()
            /Users/smy/go/src/GBlog/main.go:29 +0x89
    github.com/bamzi/jobrunner.(*Job).Run(0xc0000a7090)
            /Users/smy/go/pkg/mod/github.com/bamzi/[email protected]/jobrunner.go:75 +0x188
    github.com/robfig/cron/v3.(*Cron).startJob.func1(0xc000248b40, 0x10f8a80, 0xc0000a7090)
            /Users/smy/go/pkg/mod/github.com/robfig/cron/[email protected]/cron.go:307 +0x69
    created by github.com/robfig/cron/v3.(*Cron).startJob
            /Users/smy/go/pkg/mod/github.com/robfig/cron/[email protected]/cron.go:305 +0x73
    ^[[97;45m[JobRunner] 2020/09/07 - 09:14:54 Started... ^[[0m
    

    my code is simple as send a http get request in a every 5min job:

    func (e UpdateNews) Run() {
    	resp, err := http.Get("https://sample_site.com/common/update_news/")
    	if err != nil {
    		fmt.Println("Call update news failed")
    	}
    	var res map[string]interface{}
    	json.NewDecoder(resp.Body).Decode(&res)
    	resCode := fmt.Sprintf("%v", res["code"])
    	if resCode == "0" {
    		fmt.Printf("Every 5 mins update news success.")
    	}
    }
    func main(){
    jobrunner.Start() // optional: jobrunner.Start(pool int, concurrent int) (10, 1)
    	err := jobrunner.Schedule("@every 300s", UpdateNews{})
    	if err != nil {
    		panic(err)
    	}
    }
    
  • Custom Logger

    Custom Logger

    I think we should make it compatible with the custom logger modules created in the applications. In this way, job status can be monitored in autonomous state. I can write directly, if that's okay.

A Framework for FaaS load balancing | stack-scheduler repository|

P2PFaaS A Framework for FaaS load balancing | stack-scheduler repository Introduction The P2PFaaS is a framework that allows you to implement a load b

Oct 29, 2021
A limited Flow Access API which runs outside of the Flow Network using the DPS

Access API Flow DPS implements the Flow Access API Specification, except for the following endpoints: SendTransaction GetLatestProtocolStateSnapshot G

Jul 28, 2022
A library for performing OAuth Device flow and Web application flow in Go client apps.
A library for performing OAuth Device flow and Web application flow in Go client apps.

oauth A library for Go client applications that need to perform OAuth authorization against a server, typically GitHub.com. Traditionally,

Dec 30, 2022
A safe way to execute functions asynchronously, recovering them in case of panic. It also provides an error stack aiming to facilitate fail causes discovery.

Async Provides a safe way to execute functions asynchronously, recovering them in case of panic. It also provides an error stack aiming to facilitate

Dec 20, 2022
Asynchronously control the different roles available in the kubernetes cluster

RBAC audit Introduction This tool allows you to asynchronously control the different roles available in the kubernetes cluster. These audits are enter

Oct 19, 2021
Helps you to send ssh commands to target machine in your local network from outside via gRPC
Helps you to send ssh commands to target machine in your local network from outside via gRPC

rpc-ssh In case, you don't want to make your ssh port accessible from outside local network. This repository helps you to send ssh commands to target

Nov 16, 2022
This project aims for printing HTTP requests from outside simply

HTTP Debug Server This project aims for printing HTTP requests from outside simp

Jan 29, 2022
Minutes is a CLI tool for synchronizing work logs between multiple time trackers, invoicing, and bookkeeping software to make entrepreneurs' daily work easier.
Minutes is a CLI tool for synchronizing work logs between multiple time trackers, invoicing, and bookkeeping software to make entrepreneurs' daily work easier.

Minutes is a CLI tool for synchronizing work logs between multiple time trackers, invoicing, and bookkeeping software to make entrepreneurs' daily work easier.

Aug 8, 2022
Realize is the #1 Golang Task Runner which enhance your workflow by automating the most common tasks and using the best performing Golang live reloading.
Realize is the #1 Golang Task Runner which enhance your workflow by automating the most common tasks and using the best performing Golang live reloading.

#1 Golang live reload and task runner Content - ⭐️ Top Features - ???? Get started - ?? Config sample - ?? Commands List - ?? Support and Suggestions

Jan 6, 2023
A library for performing data pipeline / ETL tasks in Go.
A library for performing data pipeline / ETL tasks in Go.

Ratchet A library for performing data pipeline / ETL tasks in Go. The Go programming language's simplicity, execution speed, and concurrency support m

Jan 19, 2022
A Go library for performing Unicode Text Segmentation as described in Unicode Standard Annex #29

segment A Go library for performing Unicode Text Segmentation as described in Unicode Standard Annex #29 Features Currently only segmentation at Word

Dec 19, 2022
Realize is the #1 Golang Task Runner which enhance your workflow by automating the most common tasks and using the best performing Golang live reloading.
Realize is the #1 Golang Task Runner which enhance your workflow by automating the most common tasks and using the best performing Golang live reloading.

#1 Golang live reload and task runner Content - ⭐️ Top Features - ???? Get started - ?? Config sample - ?? Commands List - ?? Support and Suggestions

Dec 31, 2022
Simple system for writing HTML/XML as Go code. Better-performing replacement for html/template and text/template

Simple system for writing HTML as Go code. Use normal Go conditionals, loops and functions. Benefit from typing and code analysis. Better performance than templating. Tiny and dependency-free.

Dec 5, 2022
Goket (Golang Keyboard Event Tree) is a proof-of-concept code for using keyboard events trees for performing operations.

Goket Goket (Golang Keyboard Event Tree) is a proof-of-concept code for using keyboard events trees for performing operations. Its main goal is to all

Jan 3, 2023
A go1.18+ package to (maybe) simplify performing operations on slices in a fluent-like style.

sop ✨ W.I.P. ✨ sop (slices operation) is a go1.18+ package to (maybe) simplify performing operations on slices in a fluent-like style with common oper

Oct 1, 2022
A tool for capturing newly issued x.509 from Certificate Transparency logs & performing periodic revocation checking.

ct-logster This repository contains the tools for collecting newly issued x509 certificates from Certificate Transparency logs, as well as performing

May 4, 2022
Validate Golang request data with simple rules. Highly inspired by Laravel's request validation.
Validate Golang request data with simple rules. Highly inspired by Laravel's request validation.

Validate golang request data with simple rules. Highly inspired by Laravel's request validation. Installation Install the package using $ go get githu

Dec 29, 2022
github-actions-merger is github actions that merges pull request with commit message including pull request labels.

github-actions-merger github-actions-merger is github actions that merges pull request with commit message including pull request labels. Usage Write

Dec 7, 2022
Add request id to a request's context

RequestID ?? This is a very simple piece of middleware for adding request/correlation IDs to the context of a http request. By default, this module wi

Dec 4, 2021
Request: a HTTP request library for Go with interfaces and mocks for unit tests

Requester Request is a HTTP request library for Go with interfaces and mocks for

Jan 10, 2022