package bus import ( "context" "errors" "fmt" "io" "git.novox.be/novox/mesh-sdk/go/buscalls" "github.com/nats-io/nats.go/jetstream" ) // The bus side of a bundle's put and get sessions (design 47 G ยง518, A-21, A-25): a put written into the module's object // store as its chunks arrive and a get read out of it as they are asked, through the store's own chunking, so no more than // one chunk is held in memory. The session itself is the runtime's (internal/runtime/sessions.go). // ObjectsPutStream stores the object r.Name of the module's object store r.Objects from in, read to its end, with the // put's description (A-25); it answers once the object is sealed. A read error of in drops the object: nothing is left. func (c *Conn) ObjectsPutStream(ctx context.Context, module string, r buscalls.ObjectsNameRequest, description string, in io.Reader) (buscalls.ObjectInfo, error) { if r.Name == "" { return buscalls.ObjectInfo{}, errors.New("an object is put under a name") } obs, _, err := c.objectStore(ctx, module, r.Objects) if err != nil { return buscalls.ObjectInfo{}, err } info, err := obs.Put(ctx, jetstream.ObjectMeta{Name: r.Name, Description: description}, in) if err != nil { _ = obs.Delete(context.WithoutCancel(ctx), r.Name) return buscalls.ObjectInfo{}, err } return objectInfoOf(info), nil } // ObjectsOpen is one object of the module's object store as a reader of its bytes beside its info; found is false when there // is none. The caller closes the reader. func (c *Conn) ObjectsOpen(ctx context.Context, module string, r buscalls.ObjectsNameRequest) (info buscalls.ObjectInfo, rd io.ReadCloser, found bool, err error) { obs, _, err := c.objectStore(ctx, module, r.Objects) if err != nil { return info, nil, false, err } res, err := obs.Get(ctx, r.Name) if errors.Is(err, jetstream.ErrObjectNotFound) { return info, nil, false, nil } if err != nil { return info, nil, false, err } i, err := res.Info() if err != nil { res.Close() return info, nil, false, err } return objectInfoOf(i), res, true, nil } // SentOpen is a sent object, read by its reference as SentGet reads it, as a reader of its bytes beside its info. func (c *Conn) SentOpen(ctx context.Context, r buscalls.ObjectsSentGetRequest) (buscalls.ObjectInfo, io.ReadCloser, error) { obs, err := c.sentStore(ctx, r) if err != nil { return buscalls.ObjectInfo{}, nil, err } res, err := obs.Get(ctx, r.Object) if errors.Is(err, jetstream.ErrObjectNotFound) { return buscalls.ObjectInfo{}, nil, fmt.Errorf("the sent object %s is not in %s: it is kept 7 days, then expires", r.Object, r.Store) } if err != nil { return buscalls.ObjectInfo{}, nil, fmt.Errorf("the sent object %s of %s: %w", r.Object, r.Store, err) } i, err := res.Info() if err != nil { res.Close() return buscalls.ObjectInfo{}, nil, err } return objectInfoOf(i), res, nil }