How to exchange Data between the 2 Functions in an Efficient way ? (Maybe Contexts)
package pkg
import (
"context"
)
type Runner struct {
ch1to2 chan struct{}
ch2to1 chan struct{}
}
func New() *Runner {
return &Runner{
ch1to2: make(chan struct{}),
ch2to1: make(chan struct{}),
}
}
func (r *Runner) Run1(ctx context.Context, fn func(context.Context) error) error {
for {
select {
case <-ctx.Done():
return ctx.Err()
default:
if err := fn(ctx); err != nil {
return err
}
r.ch1to2 <- struct{}{}
<-r.ch2to1
}
}
}
func (r *Runner) Run2(ctx context.Context, fn func(context.Context) error) error {
for {
select {
case <-ctx.Done():
return ctx.Err()
case <-r.ch1to2:
if err := fn(ctx); err != nil {
return err
}
r.ch2to1 <- struct{}{}
}
}
}
Usage
package main
import (
"context"
"fmt"
runner "her/pkg"
"log"
"os"
"os/signal"
"sync"
"syscall"
"time"
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
r := runner.New()
var wg sync.WaitGroup
wg.Add(2)
go func() {
defer wg.Done()
if err := r.Run1(ctx, doWork1); err != nil {
log.Printf("Function 1 error: %v", err)
}
}()
go func() {
defer wg.Done()
if err := r.Run2(ctx, doWork2); err != nil {
log.Printf("Function 2 error: %v", err)
}
}()
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
<-sigChan
log.Println("Received interrupt signal. Shutting down...")
cancel()
wg.Wait()
log.Println("All functions have shut down. Exiting.")
}
func doWork1(ctx context.Context) error {
fmt.Printf("Function 1 running\n")
time.Sleep(5 * time.Second) // Simulate work
return nil
}
func doWork2(ctx context.Context) error {
fmt.Printf("Function 2 running\n")
time.Sleep(5 * time.Second) // Simulate work
return nil
}