/gofork

Awesome forker. Forks current Go process with additional arguments and communicate with its stdin, stdout and stderr

Primary LanguageGoMIT LicenseMIT

GoFork

Awesome forker.

Forks current Go process with additional arguments and communicate with its stdin, stdout and stderr

Usage

Recommended way to use is to activate fork in init function:

var fork gofork.Fork

func init() {
    fork = gofork.Fork{}
    if err := fork.Start("--child"); err != nil {
        panic(err)
    }
}

After fork is spawned it is possible to distinguish whether current code executes in main process or in fork by calling fork.IsFork() which returns true for forked process and false for parent process

Fork structure provides 3 channels In for Stdin of forked process, Out for Stdout and Err for Stderr. Those channels transmit strings as messages between parent and forked process. In parent process you should send messages to In and receive from Out and Err. In forked process you should receive from In and send to Out and Err

Example

TODO: Improve

package main

import (
	"github.com/akamensky/gofork"
	"fmt"
	"os"
	"errors"
	"strconv"
)

var fork gofork.Fork

func init() {
	fork = gofork.Fork{}
	if err := fork.Start("--child"); err != nil {
		panic(err)
	}
}


func main() {
	if fork.IsFork() {
		ChildRun(&fork)
	} else {
		MasterRun(&fork)
	}
}

func MasterRun(fork *gofork.Fork) {
	// Read err and if any, show err and exit
	go func(){
		err := <-fork.Err
		if err != "" {
			fork.Stop()
			panic(errors.New(err))
			os.Exit(1)
		}
	}()
	nums := []int{1,2,3,4,5}
	for _, num := range nums {
		fork.In<- fmt.Sprintf("%d", num)
		fmt.Println(<-fork.Out)
	}
}

func ChildRun(fork *gofork.Fork) {
	for {
		number, err := strconv.Atoi(<-fork.In)
		if err != nil {
			fork.Err<- err.Error()
			os.Exit(1)
		}
		fork.Out<- fmt.Sprintf("%d", number*number)
	}
}