synchrozine

package module
v2.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 28, 2020 License: MIT Imports: 2 Imported by: 0

README

synchrozine

Build Status

Synchrozine is an instrument for synchronization of multiple goroutines over a single channel. It contains the main channel (chan error), WaitGroup for complete synchronization and receivers a channels list to send finish signals to goroutines.

Synchrozine supports the startup synchronization and thread-safe injections.

Installation

go mod init github.com/my/repo
go get github.com/Devoter/synchrozine/v2

Usage

It is easy to use Synchrozine and simular to sync.WaitGroup. We have five lifecycle steps:

  1. Goroutines declaration
  2. Goroutines registration
  3. Startup synchronization
  4. Injection
  5. Final synchronization
Goroutines declaration

At first you should declare that a goroutine will be registered. Call Add() before start the goroutine.

synchro.Add()
go func() {
	// do something
}()
Goroutines registration

The next step is to register the declared goroutine. Call Done() before exit from the goroutine, get and listen a finish channel (Append()).

go func() {
	defer synchro.Done()

	finishChan := synchro.Append()

	for {
		select {
		case <-finishChan:
			return
		case <-time.After(100 * time.Millisecond): // any event
			// do something
		}
	}
}
Startup synchronization

Startup synchronization is optional, but if you want to be sure that all controlled goroutines have registered successfully call StartSync() in the parent goroutine.

synchro.StartSync()
Injection

It is important that Inject() does not stops controlled goroutines. It just sends a message to the Synchrozine instance. This is a non-blocking method regardless of number of calls.

synchro.Inject(fmt.Errorf("stop all"))
Final synchronization

In your parent goroutine insert a Sync() call. This method will wait for the injection. After that, it will have broadcast finish signals to controlled goroutines and wait for synchronization. This is a blocking method.

synchro.Sync()
Example
package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/Devoter/synchrozine/v2"
)

func main() {
	listen := flag.String("listen", ":8080", "HTTP listen address")

	flag.Parse()

	synchro := synchrozine.New()

	// Waiting for sigint or sigterm
	go func() {
		c := make(chan os.Signal)
		signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
		synchro.Inject(fmt.Errorf("%s", <-c))
		log.Println("signal received")
	}()

	go func() {
		log.Println("starting server...")
		log.Println("addr", *listen)
		synchro.Inject(http.ListenAndServe(*listen, nil))
		log.Println("server stopped")
	}()

	synchro.Add()
	go func() {
		defer synchro.Done()

		finishChan := synchro.Append()

		const increment = 5
		var counter int

		for {
			// do something
			select {
			case <-finishChan:
				log.Println("finish something")
				return
			case <-time.After(increment * time.Second):
				counter += increment
				log.Printf("%d seconds left\n", counter)
			}
		}
	}()

	synchro.StartupSync() // optional, just if you want to be sure that all goroutines have started

	log.Println("exit: ", synchro.Sync())
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Synchrozine

type Synchrozine struct {
	// contains filtered or unexported fields
}

Synchrozine is a complex solution for synchronization of multiple goroutines over a single channel. It contains the main channel (`chan error`), WaitGroup for complete synchronization and receivers channels list to send finish signals to goroutines.

func New

func New() *Synchrozine

New creates a initialized instance of Synchrozine.

func (*Synchrozine) Add

func (s *Synchrozine) Add()

Add increments a counter of the internal WaitGroup (see `sync.WaitGroup`).

func (*Synchrozine) Append

func (s *Synchrozine) Append() <-chan bool

Append creates a buffered receiver channel, adds it to the receivers list and returns for as read-only channel.

func (*Synchrozine) Done

func (s *Synchrozine) Done()

Done decrements a counte of the internal WaitGroup (see `sync.WaitGroup`).

func (*Synchrozine) Inject

func (s *Synchrozine) Inject(err error)

Inject sends a sync message.

func (*Synchrozine) StartupSync

func (s *Synchrozine) StartupSync()

StartupSync waits for all appended goroutines to start.

func (*Synchrozine) Sync

func (s *Synchrozine) Sync() error

Sync waits for a sync message, sends messages to receivers, and waits for goroutines completion.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL