G sessions: the runner serves a bundle's put and get sessions and states put-sessions
A value over buscalls.ChunkBytes is put by mesh/objects.put-chunk (written into the module's store as each chunk is taken, sealed on the last, dropped at its bound or a disorder) and got by mesh/objects.get-chunk after a chunked answer, for a state's object and a sent object alike; the 8 MiB BundleObjectMost cap is gone with the stateobjects constant. Builds: design 47 G §518, §345, §457, §490, §620, §622, A-21, A-25 Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
@@ -1,13 +1,16 @@
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"sort"
|
||||
|
||||
stdio "git.novox.be/novox/mesh-sdk/go"
|
||||
"git.novox.be/novox/mesh-sdk/go/buscalls"
|
||||
"git.novox.be/novox/mesh-sdk/go/stateobjects"
|
||||
|
||||
"github.com/novox/mesh-tools/node-tools/internal/bus"
|
||||
)
|
||||
|
||||
// The capabilities the tool runner states of the calls it answers (novox/hq ADR 0595 §9, ADR 0597; design 25 § 12.4): each is
|
||||
@@ -17,6 +20,8 @@ import (
|
||||
const (
|
||||
CapBusStateCalls = "bus-state-calls"
|
||||
CapLedgerCalls = "ledger-calls"
|
||||
// CapPutSessions is the put and get sessions' word (design 47 G §518, §622), mesh-sdk's.
|
||||
CapPutSessions = stdio.CapPutSessions
|
||||
)
|
||||
|
||||
// callFamilies are the methods each capability stands for, the ones BusState and BusStateWatch answer.
|
||||
@@ -25,6 +30,7 @@ var callFamilies = map[string][]string{
|
||||
buscalls.ObjectsWatch, buscalls.ObjectsSentGet, buscalls.StreamRead, buscalls.StreamFill, buscalls.WorkQueueSize, buscalls.WorkQueueDead},
|
||||
CapLedgerCalls: {buscalls.LedgerApply, buscalls.LedgerGet, buscalls.LedgerHistory, buscalls.LedgerWatch, buscalls.LedgerQuery,
|
||||
buscalls.LedgerRebuild, buscalls.LedgerReindex, buscalls.LedgerSnapshot, buscalls.LedgerLag},
|
||||
CapPutSessions: {buscalls.ObjectsPutChunk, buscalls.ObjectsGetChunk},
|
||||
}
|
||||
|
||||
// CallCapabilities is every capability of the calls this runner answers, sorted. The delayed settle of a pulled seat
|
||||
@@ -54,11 +60,10 @@ func (b *moduleBus) BusState(method string, params json.RawMessage) (json.RawMes
|
||||
case buscalls.ObjectsGet:
|
||||
var r buscalls.ObjectsNameRequest
|
||||
if err = decode(method, params, &r); err == nil {
|
||||
var got *buscalls.ObjectData
|
||||
if got, err = conn.ObjectsGet(b.module, r); err == nil && got == nil {
|
||||
answer, err = b.all.objectsGet(b.module, r)
|
||||
if err == nil && answer == nil {
|
||||
return json.RawMessage("null"), nil
|
||||
}
|
||||
answer = got
|
||||
}
|
||||
case buscalls.ObjectsDelete:
|
||||
var r buscalls.ObjectsNameRequest
|
||||
@@ -69,14 +74,12 @@ func (b *moduleBus) BusState(method string, params json.RawMessage) (json.RawMes
|
||||
case buscalls.ObjectsSentGet:
|
||||
var r buscalls.ObjectsSentGetRequest
|
||||
if err = decode(method, params, &r); err == nil {
|
||||
var got *buscalls.ObjectData
|
||||
if r.Size > stateobjects.BundleObjectMost {
|
||||
// Only the bundle's channel is limited (design 47 "Any size"): the console reads a larger one whole.
|
||||
err = fmt.Errorf("the sent object %s is %d bytes and a bundle's runtime channel carries at most %d: it is not read through a bundle", r.Object, r.Size, stateobjects.BundleObjectMost)
|
||||
} else if got, err = conn.SentGet(r); err == nil {
|
||||
answer = got
|
||||
}
|
||||
answer, err = b.all.sentGet(b.module, r)
|
||||
}
|
||||
case buscalls.ObjectsPutChunk:
|
||||
answer, err = b.all.putChunk(b.module, params)
|
||||
case buscalls.ObjectsGetChunk:
|
||||
answer, err = b.all.getChunk(b.module, params)
|
||||
case buscalls.ObjectsList:
|
||||
var r buscalls.ObjectsRequest
|
||||
if err = decode(method, params, &r); err == nil {
|
||||
@@ -147,3 +150,50 @@ func decode(method string, params json.RawMessage, into any) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// objectsGet answers a get: the object whole when it is at most one chunk, else the session that reads it chunk by chunk
|
||||
// (design 47 G §490, §518); nil when there is none.
|
||||
func (c *consumers) objectsGet(module string, r buscalls.ObjectsNameRequest) (any, error) {
|
||||
st := c.objects()
|
||||
if st == nil {
|
||||
return nil, fmt.Errorf("the runner has no bus to read %s of %s from", r.Name, module)
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), bus.StateTimeout)
|
||||
defer cancel()
|
||||
info, rd, found, err := st.ObjectsOpen(ctx, module, r)
|
||||
if err != nil || !found {
|
||||
return nil, err
|
||||
}
|
||||
if info.Size > buscalls.ChunkBytes {
|
||||
return c.openGet(module, info, rd, sessionDigest(info.Digest), false)
|
||||
}
|
||||
defer rd.Close()
|
||||
data, err := io.ReadAll(rd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &buscalls.ObjectData{Info: info, Data: data}, nil
|
||||
}
|
||||
|
||||
// sentGet answers a get of a sent object by its reference: whole when the reference's size is at most one chunk, else a
|
||||
// session (design 47 G §620).
|
||||
func (c *consumers) sentGet(module string, r buscalls.ObjectsSentGetRequest) (any, error) {
|
||||
if r.Size <= buscalls.ChunkBytes {
|
||||
got, err := c.conn.SentGet(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return got, nil
|
||||
}
|
||||
st := c.objects()
|
||||
if st == nil {
|
||||
return nil, fmt.Errorf("the runner has no bus to read %s from", r.Object)
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), bus.StateTimeout)
|
||||
defer cancel()
|
||||
info, rd, err := st.SentOpen(ctx, r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c.openGet(module, info, rd, sessionDigest(r.Digest), true)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user