|
- package ops
-
- import (
- "context"
- "fmt"
- "io"
-
- "gitlink.org.cn/cloudream/common/pkgs/future"
- "gitlink.org.cn/cloudream/storage/common/pkgs/ioswitch"
- )
-
- type OnStreamBegin struct {
- Raw *ioswitch.StreamVar `json:"raw"`
- New *ioswitch.StreamVar `json:"new"`
- Signal *ioswitch.SignalVar `json:"signal"`
- }
-
- func (o *OnStreamBegin) Execute(ctx context.Context, sw *ioswitch.Switch) error {
- err := sw.BindVars(ctx, o.Raw)
- if err != nil {
- return err
- }
-
- o.New.Stream = o.Raw.Stream
-
- sw.PutVars(o.New, o.Signal)
- return nil
- }
-
- type OnStreamEnd struct {
- Raw *ioswitch.StreamVar `json:"raw"`
- New *ioswitch.StreamVar `json:"new"`
- Signal *ioswitch.SignalVar `json:"signal"`
- }
-
- type onStreamEnd struct {
- inner io.ReadCloser
- callback *future.SetVoidFuture
- }
-
- func (o *onStreamEnd) Read(p []byte) (n int, err error) {
- n, err = o.inner.Read(p)
- if err == io.EOF {
- o.callback.SetVoid()
- } else if err != nil {
- o.callback.SetError(err)
- }
- return n, err
- }
-
- func (o *onStreamEnd) Close() error {
- o.callback.SetError(fmt.Errorf("stream closed early"))
- return o.inner.Close()
- }
-
- func (o *OnStreamEnd) Execute(ctx context.Context, sw *ioswitch.Switch) error {
- err := sw.BindVars(ctx, o.Raw)
- if err != nil {
- return err
- }
-
- cb := future.NewSetVoid()
-
- o.New.Stream = &onStreamEnd{
- inner: o.Raw.Stream,
- callback: cb,
- }
- sw.PutVars(o.New)
-
- err = cb.Wait(ctx)
- if err != nil {
- return err
- }
-
- sw.PutVars(o.Signal)
- return nil
- }
-
- type HoldUntil struct {
- Waits []*ioswitch.SignalVar `json:"waits"`
- Holds []ioswitch.Var `json:"holds"`
- Emits []ioswitch.Var `json:"emits"`
- }
-
- func (w *HoldUntil) Execute(ctx context.Context, sw *ioswitch.Switch) error {
- err := sw.BindVars(ctx, w.Holds...)
- if err != nil {
- return err
- }
-
- err = ioswitch.BindArrayVars(sw, ctx, w.Waits)
- if err != nil {
- return err
- }
-
- for i := 0; i < len(w.Holds); i++ {
- err := ioswitch.AssignVar(w.Holds[i], w.Emits[i])
- if err != nil {
- return err
- }
- }
-
- sw.PutVars(w.Emits...)
- return nil
- }
-
- type HangUntil struct {
- Waits []*ioswitch.SignalVar `json:"waits"`
- Op ioswitch.Op `json:"op"`
- }
-
- func (h *HangUntil) Execute(ctx context.Context, sw *ioswitch.Switch) error {
- err := ioswitch.BindArrayVars(sw, ctx, h.Waits)
- if err != nil {
- return err
- }
-
- return h.Op.Execute(ctx, sw)
- }
-
- type Broadcast struct {
- Source *ioswitch.SignalVar `json:"source"`
- Targets []*ioswitch.SignalVar `json:"targets"`
- }
-
- func (b *Broadcast) Execute(ctx context.Context, sw *ioswitch.Switch) error {
- err := sw.BindVars(ctx, b.Source)
- if err != nil {
- return err
- }
-
- ioswitch.PutArrayVars(sw, b.Targets)
- return nil
- }
-
- func init() {
- OpUnion.AddT((*OnStreamBegin)(nil))
- OpUnion.AddT((*OnStreamEnd)(nil))
- OpUnion.AddT((*HoldUntil)(nil))
- OpUnion.AddT((*HangUntil)(nil))
- OpUnion.AddT((*Broadcast)(nil))
- }
|