aboutsummaryrefslogtreecommitdiffhomepage
path: root/cmd
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2026-04-17 16:46:49 +0900
committerOphestra <cat@gensokyo.uk>2026-04-17 16:46:49 +0900
commit90369861568d38737001f1d7e1304e6914675359 (patch)
treea0546950f7030dc1b807b8e8502dd070235d331b /cmd
parenta394971dd75d8ad0287197553d3717dfb1d11b74 (diff)
cmd/mbf: optionally ignore reply
An acknowledgement is not always required in this use case. This change also adds 64 bits of connection configuration for future expansion. Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'cmd')
-rw-r--r--cmd/mbf/daemon.go47
-rw-r--r--cmd/mbf/daemon_test.go11
-rw-r--r--cmd/mbf/main.go21
3 files changed, 57 insertions, 22 deletions
diff --git a/cmd/mbf/daemon.go b/cmd/mbf/daemon.go
index 22eeb72b..d64643d2 100644
--- a/cmd/mbf/daemon.go
+++ b/cmd/mbf/daemon.go
@@ -2,6 +2,7 @@ package main
import (
"context"
+ "encoding/binary"
"errors"
"io"
"log"
@@ -27,21 +28,28 @@ func daemonDeadline() time.Time {
return time.Now().Add(daemonTimeout)
}
+const (
+ // remoteNoReply notifies that the client will not receive a cure reply.
+ remoteNoReply = 1 << iota
+)
+
// cureFromIR services an IR curing request.
func cureFromIR(
ctx context.Context,
cache *pkg.Cache,
conn net.Conn,
) (pkg.Artifact, error) {
- go func() {
- <-ctx.Done()
- _ = conn.SetDeadline(time.Now())
- }()
-
+ go func() { <-ctx.Done(); _ = conn.SetDeadline(time.Now()) }()
if err := conn.SetReadDeadline(daemonDeadline()); err != nil {
return nil, errors.Join(err, conn.Close())
}
+ var flagsWire [8]byte
+ if _, err := io.ReadFull(conn, flagsWire[:]); err != nil {
+ return nil, errors.Join(err, conn.Close())
+ }
+ flags := binary.LittleEndian.Uint64(flagsWire[:])
+
a, decodeErr := cache.NewDecoder(conn).Decode()
if decodeErr != nil {
_, err := conn.Write([]byte("\x00" + decodeErr.Error()))
@@ -49,10 +57,11 @@ func cureFromIR(
}
pathname, _, cureErr := cache.Cure(a)
+ if flags&remoteNoReply != 0 {
+ return a, errors.Join(cureErr, conn.Close())
+ }
if err := conn.SetWriteDeadline(daemonDeadline()); err != nil {
- if !testing.Testing() || !errors.Is(err, io.ErrClosedPipe) {
- return a, errors.Join(err, conn.Close())
- }
+ return a, errors.Join(cureErr, err, conn.Close())
}
if cureErr != nil {
_, err := conn.Write([]byte("\x00" + cureErr.Error()))
@@ -66,7 +75,12 @@ func cureFromIR(
}
// serve services connections from a [net.UnixListener].
-func serve(ctx context.Context, log *log.Logger, cm *cache, ul *net.UnixListener) error {
+func serve(
+ ctx context.Context,
+ log *log.Logger,
+ cm *cache,
+ ul *net.UnixListener,
+) error {
ul.SetUnlinkOnClose(true)
if cm.c == nil {
if err := cm.open(); err != nil {
@@ -116,16 +130,19 @@ func cureRemote(
ctx context.Context,
addr *net.UnixAddr,
a pkg.Artifact,
+ flags uint64,
) (*check.Absolute, error) {
conn, err := net.DialUnix("unix", nil, addr)
if err != nil {
return nil, err
}
+ go func() { <-ctx.Done(); _ = conn.SetDeadline(time.Now()) }()
- go func() {
- <-ctx.Done()
- _ = conn.SetDeadline(time.Now())
- }()
+ if n, flagErr := conn.Write(binary.LittleEndian.AppendUint64(nil, flags)); flagErr != nil {
+ return nil, errors.Join(flagErr, conn.Close())
+ } else if n != 8 {
+ return nil, errors.Join(io.ErrShortWrite, conn.Close())
+ }
if err = pkg.NewIR().EncodeAll(conn, a); err != nil {
return nil, errors.Join(err, conn.Close())
@@ -133,6 +150,10 @@ func cureRemote(
return nil, errors.Join(err, conn.Close())
}
+ if flags&remoteNoReply != 0 {
+ return nil, conn.Close()
+ }
+
payload, recvErr := io.ReadAll(conn)
if err = errors.Join(recvErr, conn.Close()); err != nil {
if errors.Is(err, os.ErrDeadlineExceeded) {
diff --git a/cmd/mbf/daemon_test.go b/cmd/mbf/daemon_test.go
index cf67059a..2ec2e76a 100644
--- a/cmd/mbf/daemon_test.go
+++ b/cmd/mbf/daemon_test.go
@@ -3,6 +3,7 @@ package main
import (
"bytes"
"context"
+ "encoding/binary"
"errors"
"io"
"log"
@@ -17,7 +18,7 @@ import (
"hakurei.app/message"
)
-func TestCureFromIR(t *testing.T) {
+func TestNoReply(t *testing.T) {
t.Parallel()
if !daemonDeadline().IsZero() {
t.Fatal("daemonDeadline did not return the zero value")
@@ -45,7 +46,11 @@ func TestCureFromIR(t *testing.T) {
}
}()
- if _err := c.EncodeAll(
+ if _, _err := client.Write(
+ binary.LittleEndian.AppendUint64(nil, remoteNoReply),
+ ); _err != nil {
+ panic(_err)
+ } else if _err = c.EncodeAll(
client,
pkg.NewFile("check", []byte{0}),
); _err != nil {
@@ -105,7 +110,7 @@ func TestDaemon(t *testing.T) {
}()
var p *check.Absolute
- p, err = cureRemote(ctx, &addr, pkg.NewFile("check", []byte{0}))
+ p, err = cureRemote(ctx, &addr, pkg.NewFile("check", []byte{0}), 0)
if err != nil {
t.Fatalf("cureRemote: error = %v", err)
}
diff --git a/cmd/mbf/main.go b/cmd/mbf/main.go
index abdc5e94..bee97b01 100644
--- a/cmd/mbf/main.go
+++ b/cmd/mbf/main.go
@@ -392,10 +392,11 @@ func main() {
{
var (
- flagDump string
- flagEnter bool
- flagExport string
- flagRemote bool
+ flagDump string
+ flagEnter bool
+ flagExport string
+ flagRemote bool
+ flagNoReply bool
)
c.NewCommand(
"cure",
@@ -474,8 +475,12 @@ func main() {
})
case flagRemote:
- pathname, err := cureRemote(ctx, &addr, rosa.Std.Load(p))
- if err == nil {
+ var flags uint64
+ if flagNoReply {
+ flags |= remoteNoReply
+ }
+ pathname, err := cureRemote(ctx, &addr, rosa.Std.Load(p), flags)
+ if !flagNoReply && err == nil {
log.Println(pathname)
}
return err
@@ -497,6 +502,10 @@ func main() {
&flagRemote,
"daemon", command.BoolFlag(false),
"Cure artifact on the daemon",
+ ).Flag(
+ &flagNoReply,
+ "no-reply", command.BoolFlag(false),
+ "Do not receive a reply from the daemon",
)
}