Skip to content
This repository has been archived by the owner on Feb 20, 2024. It is now read-only.

Commit

Permalink
Merge pull request #29 from catmullet/update-readme
Browse files Browse the repository at this point in the history
Update README.md (WIP)
  • Loading branch information
ebarti authored Jun 3, 2021
2 parents 3b03dab + 3a3b3eb commit ae53f26
Showing 1 changed file with 23 additions and 22 deletions.
45 changes: 23 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ go get github.com/catmullet/go-workers

### Add the import to your project
giving an alias helps since go-workers doesn't exactly follow conventions.
_(If your using a JetBrains IDE it should automatically give it an alias)_
_(If you're using a JetBrains IDE it should automatically give it an alias)_
```go
import (
worker "github.com/catmullet/go-workers"
workers "github.com/catmullet/go-workers"
)
```
### Create a new worker <img src="https://raw.githubusercontent.com/catmullet/go-workers/assets/constworker.png" alt="worker" width="35"/>
Expand All @@ -29,25 +29,25 @@ _(Method chaining can be performed on this method like calling .Work() immediate
```go
type MyWorker struct {}

func NewMyWorker() *MyWorker {
func NewMyWorker() Worker {
return &MyWorker{}
}

func (my *MyWorker) Work(w *goworker.Worker, in interface{}) error {
func (my *MyWorker) Work(in interface{}, out chan<- interface{}) error {
// work iteration here
}

worker := worker.NewWorker(ctx, NewMyWorker(), numberOfWorkers)
runner := workers.NewRunner(ctx, NewMyWorker(), numberOfWorkers)
```
### Send work to worker
Send accepts an interface. So send it anything you want.
```go
worker.Send("Hello World")
runner.Send("Hello World")
```
### Close and wait for the worker to finish and handle errors
### Wait for the worker to finish and handle errors
Any error that bubbles up from your worker functions will return here.
```go
if err := worker.Close(); err != nil {
if err := runner.Wait(); err != nil {
//Handle error
}
```
Expand All @@ -57,48 +57,49 @@ if err := worker.Close(); err != nil {

By using the InFrom method you can tell `workerTwo` to accept output from `workerOne`
```go
workerOne := worker.NewWorker(ctx, NewMyWorker(), 100).Work()
workerTwo := worker.NewWorker(ctx, NewMyWorkerTwo(), 100).InFrom(workerOne).Work()
runnerOne := workers.NewRunner(ctx, NewMyWorker(), 100).Work()
runnerTwo := workers.NewRunner(ctx, NewMyWorkerTwo(), 100).InFrom(workerOne).Work()
```
### Accepting output from multiple workers
It is possible to accept output from more than one worker but it is up to you to determine what is coming from which worker. (They will send on the same channel.)
```go
workerOne := worker.NewWorker(ctx, NewMyWorker(), 100).Work()
workerTwo := worker.NewWorker(ctx, NewMyWorkerTwo(), 100).Work()
workerThree := worker.NewWorker(ctx, NewMyWorkerThree(), 100).InFrom(workerOne, workerTwo).Work()
runnerOne := workers.NewRunner(ctx, NewMyWorker(), 100).Work()
runnerTwo := workers.NewRunner(ctx, NewMyWorkerTwo(), 100).Work()
runnerThree := workers.NewRunner(ctx, NewMyWorkerThree(), 100).InFrom(workerOne, workerTwo).Work()
```

## Passing Fields To Workers
### Adding Values
Fields can be passed via the workers object. Be sure as with any concurrency in Golang that your variables are concurrent safe. Most often the golang documentation will state the package or parts of it are concurrent safe. If it does not state so there is a good chance it isn't. Use the sync package to lock and unlock for writes on unsafe variables. (It is good practice NOT to defer in the work function.)

<img src="https://raw.githubusercontent.com/catmullet/go-workers/assets/constworker2.png" alt="worker" width="35"/> **ONLY** use the `Send()` method to get data into your worker. It is not shared memory unlike the worker objects values.

```go
type MyWorker struct {
message string
}

func NewMyWorker(message string) *MyWorker {
func NewMyWorker(message string) Worker {
return &MyWorker{message}
}

func (my *MyWorker) Work(w *goworker.Worker, in interface{}) error {
func (my *MyWorker) Work(in interface{}, out chan<- interface{}) error {
fmt.Println(my.message)
}

worker := worker.NewWorker(ctx, NewMyWorker(), 100).Work()
runner := workers.NewRunner(ctx, NewMyWorker(), 100).Work()
```

### Setting Timeouts or Deadlines
If your workers needs to stop at a deadline or you just need to have a timeout use the SetTimeout or SetDeadline methods. (These must be in place before setting the workers off to work.)
```go
// Setting a timeout of 2 seconds
timeoutWorker.SetTimeout(2 * time.Second)
timeoutRunner.SetTimeout(2 * time.Second)

// Setting a deadline of 4 hours from now
deadlineWorker.SetDeadline(time.Now().Add(4 * time.Hour))
deadlineRunner.SetDeadline(time.Now().Add(4 * time.Hour))

func workerFunction(w *worker.Worker, in interface{}) error {
func workerFunction(in interface{}, out chan<- interface{} error {
fmt.Println(in)
time.Sleep(1 * time.Second)
}
Expand All @@ -109,9 +110,9 @@ func workerFunction(w *worker.Worker, in interface{}) error {
### Buffered Writer
If you want to write out to a file or just stdout you can use SetWriterOut(writer io.Writer). The worker will have the following methods available
```go
worker.Println()
worker.Printf()
worker.Print()
runner.Println()
runner.Printf()
runner.Print()
```
The workers use a buffered writer for output and can be up to 3 times faster than the fmt package. Just be mindful it won't write out to the console as quickly as an unbuffered writer. It will sync and eventually flush everything at the end, making it ideal for writing out to a file.

Expand Down

0 comments on commit ae53f26

Please sign in to comment.