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
}