Skip to content

Channel-like semantics over net/rpc

License

Notifications You must be signed in to change notification settings

lucafmarques/rpchan

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

rpchan: channel-like semantics over net/rpc

coverage Go Reference Go Report Card

rpchan provides channel-like semantics over a TCP connection using net/rpc.

go get github.com/lucafmarques/rpchan

It achieves this by providing a minimal API on the RPChan[T any] type:

  • Use Send if you want to send a T, similarly to ch <- T
  • Use Receive if you want to receive a T, similarly to <-ch
  • Use Close if you want to close the channel, similarly to close(ch)
  • Use Listen if want to iterate on the channel, similarly to for v := range ch

Those four methods are enough to mimic one-way send/receive channel-like semantics.

Be mindful that since network calls are involved, error returns are needed to allow callers to react to network errors.

It's advisable, but not mandatory, to use the same type on both the receiver and sender. This is because rpchan follows the encoding/gob guidelines for encoding types and values.

Examples

sender.go receiver.go
package main

import (
    "github.com/lucafmarques/rpchan"
)

func main() {
    ch := rpchan.New[int](":9091")
    err := ch.Send(20)
    // ... error handling
    err = ch.Close()
}
package main

import (
    "github.com/lucafmarques/rpchan"
)

func main() {
    ch := rpchan.New[int](":9091", 100)
    for v, err := range ch.Listen() {
        // ... error handling + use v
    }
}

Tasks

This project uses xc for executing tasks, below are the tasks that you can execute, and exactly what they do.

test

Test the whole package or any of its test functions matching the string input.

inputs: FUNC,FLAG
env: FUNC=
env: FLAG=

export GOEXPERIMENT=rangefunc

if test -n "$FUNC"; then RUN="-run $FUNC"; fi
if test -n "$FLAG"; then FLG="-$FLAG"; fi
go test ./... $RUN $FLG

coverage

Generate test coverage and open an HTML of it on the default browser.

inputs: OPEN
env: OPEN=yes

export GOEXPERIMENT=rangefunc

go test -v -coverprofile=coverage.out ./... && \
go tool cover -html coverage.out -o coverage.html
go tool cover -func=coverage.out -o=coverage.out
if [ "$OPEN" = "yes" ]; then xdg-open coverage.html; fi

tag

Creates new major|minor|patch tag.

requires: test
inputs: VERSION
env: VERSION=patch

git fetch --tags || true

CURR_VERSION=`git describe --abbrev=0 --tags 2>/dev/null`
SPLITS=(${CURR_VERSION//./ })
MAJOR=${SPLITS[0]//v}
MINOR=${SPLITS[1]}
PATCH=${SPLITS[2]}

case $VERSION in
    major) MAJOR=$((MAJOR+1)) && MINOR=0 && PATCH=0 ;;
    minor) MINOR=$((MINOR+1)) && PATCH=0 ;;
    patch) PATCH=$((PATCH+1)) ;;
esac 

TAG="v$MAJOR.$MINOR.$PATCH"
git tag -s $TAG -m "tag($VERSION): Release version $TAG"

rangefunc

If built with Go 1.22 and GOEXPERIMENT=rangefunc, the Listen method can be used on a for-range loop, working exactly like a Go channel would.


README.md inspired by sourcegraph/conc