package ops2 import ( "fmt" "gitlink.org.cn/cloudream/common/pkgs/ioswitch/dag" "gitlink.org.cn/cloudream/common/pkgs/ioswitch/exec" clitypes "gitlink.org.cn/cloudream/storage2/client/types" "gitlink.org.cn/cloudream/storage2/common/pkgs/storage/pool" "gitlink.org.cn/cloudream/storage2/common/pkgs/storage/types" ) func init() { exec.UseOp[*BypassToShardStore]() exec.UseVarValue[*BypassUploadedFileValue]() exec.UseVarValue[*BypassHandleResultValue]() exec.UseOp[*BypassFromShardStore]() exec.UseVarValue[*BypassFilePathValue]() exec.UseOp[*BypassFromShardStoreHTTP]() exec.UseVarValue[*HTTPRequestValue]() } type BypassUploadedFileValue struct { types.BypassUploadedFile } func (v *BypassUploadedFileValue) Clone() exec.VarValue { return &BypassUploadedFileValue{ BypassUploadedFile: v.BypassUploadedFile, } } type BypassHandleResultValue struct { Commited bool } func (r *BypassHandleResultValue) Clone() exec.VarValue { return &BypassHandleResultValue{ Commited: r.Commited, } } type BypassToShardStore struct { UserSpace clitypes.UserSpaceDetail BypassFileInfo exec.VarID BypassCallback exec.VarID FileHash exec.VarID } func (o *BypassToShardStore) Execute(ctx *exec.ExecContext, e *exec.Executor) error { stgPool, err := exec.GetValueByType[*pool.Pool](ctx) if err != nil { return err } shardStore, err := stgPool.GetShardStore(&o.UserSpace) if err != nil { return err } br, ok := shardStore.(types.BypassWrite) if !ok { return fmt.Errorf("shard store %v not support bypass write", o.UserSpace) } fileInfo, err := exec.BindVar[*BypassUploadedFileValue](e, ctx.Context, o.BypassFileInfo) if err != nil { return err } err = br.BypassUploaded(fileInfo.BypassUploadedFile) if err != nil { return err } e.PutVar(o.BypassCallback, &BypassHandleResultValue{Commited: true}) e.PutVar(o.FileHash, &ShardInfoValue{Hash: fileInfo.Hash, Size: fileInfo.Size}) return nil } func (o *BypassToShardStore) String() string { return fmt.Sprintf("BypassToShardStore[UserSpace:%v] Info: %v, Callback: %v", o.UserSpace, o.BypassFileInfo, o.BypassCallback) } type BypassFilePathValue struct { types.BypassFilePath } func (v *BypassFilePathValue) Clone() exec.VarValue { return &BypassFilePathValue{ BypassFilePath: v.BypassFilePath, } } type BypassFromShardStore struct { UserSpace clitypes.UserSpaceDetail FileHash clitypes.FileHash Output exec.VarID } func (o *BypassFromShardStore) Execute(ctx *exec.ExecContext, e *exec.Executor) error { stgPool, err := exec.GetValueByType[*pool.Pool](ctx) if err != nil { return err } shardStore, err := stgPool.GetShardStore(&o.UserSpace) if err != nil { return err } br, ok := shardStore.(types.BypassRead) if !ok { return fmt.Errorf("shard store %v not support bypass read", o.UserSpace) } path, err := br.BypassRead(o.FileHash) if err != nil { return err } e.PutVar(o.Output, &BypassFilePathValue{BypassFilePath: path}) return nil } func (o *BypassFromShardStore) String() string { return fmt.Sprintf("BypassFromShardStore[UserSpace:%v] FileHash: %v, Output: %v", o.UserSpace, o.FileHash, o.Output) } // 旁路Http读取 type BypassFromShardStoreHTTP struct { UserSpace clitypes.UserSpaceDetail FileHash clitypes.FileHash Output exec.VarID } type HTTPRequestValue struct { types.HTTPRequest } func (v *HTTPRequestValue) Clone() exec.VarValue { return &HTTPRequestValue{ HTTPRequest: v.HTTPRequest, } } func (o *BypassFromShardStoreHTTP) Execute(ctx *exec.ExecContext, e *exec.Executor) error { stgPool, err := exec.GetValueByType[*pool.Pool](ctx) if err != nil { return err } shardStore, err := stgPool.GetShardStore(&o.UserSpace) if err != nil { return err } br, ok := shardStore.(types.HTTPBypassRead) if !ok { return fmt.Errorf("shard store %v not support bypass read", o.UserSpace) } req, err := br.HTTPBypassRead(o.FileHash) if err != nil { return err } e.PutVar(o.Output, &HTTPRequestValue{HTTPRequest: req}) return nil } func (o *BypassFromShardStoreHTTP) String() string { return fmt.Sprintf("BypassFromShardStoreHTTP[UserSpace:%v] FileHash: %v, Output: %v", o.UserSpace, o.FileHash, o.Output) } // 旁路写入 type BypassToShardStoreNode struct { dag.NodeBase UserSpace clitypes.UserSpaceDetail FileHashStoreKey string } func (b *GraphNodeBuilder) NewBypassToShardStore(userSpace clitypes.UserSpaceDetail, fileHashStoreKey string) *BypassToShardStoreNode { node := &BypassToShardStoreNode{ UserSpace: userSpace, FileHashStoreKey: fileHashStoreKey, } b.AddNode(node) node.InputValues().Init(1) node.OutputValues().Init(node, 2) return node } func (n *BypassToShardStoreNode) BypassFileInfoSlot() dag.ValueInputSlot { return dag.ValueInputSlot{ Node: n, Index: 0, } } func (n *BypassToShardStoreNode) BypassCallbackVar() dag.ValueOutputSlot { return dag.ValueOutputSlot{ Node: n, Index: 0, } } func (n *BypassToShardStoreNode) FileHashVar() dag.ValueOutputSlot { return dag.ValueOutputSlot{ Node: n, Index: 1, } } func (t *BypassToShardStoreNode) GenerateOp() (exec.Op, error) { return &BypassToShardStore{ UserSpace: t.UserSpace, BypassFileInfo: t.BypassFileInfoSlot().Var().VarID, BypassCallback: t.BypassCallbackVar().Var().VarID, FileHash: t.FileHashVar().Var().VarID, }, nil } // 旁路读取 type BypassFromShardStoreNode struct { dag.NodeBase UserSpace clitypes.UserSpaceDetail FileHash clitypes.FileHash } func (b *GraphNodeBuilder) NewBypassFromShardStore(userSpace clitypes.UserSpaceDetail, fileHash clitypes.FileHash) *BypassFromShardStoreNode { node := &BypassFromShardStoreNode{ UserSpace: userSpace, FileHash: fileHash, } b.AddNode(node) node.OutputValues().Init(node, 1) return node } func (n *BypassFromShardStoreNode) FilePathVar() dag.ValueOutputSlot { return dag.ValueOutputSlot{ Node: n, Index: 0, } } func (n *BypassFromShardStoreNode) GenerateOp() (exec.Op, error) { return &BypassFromShardStore{ UserSpace: n.UserSpace, FileHash: n.FileHash, Output: n.FilePathVar().Var().VarID, }, nil } // 旁路Http读取 type BypassFromShardStoreHTTPNode struct { dag.NodeBase UserSpace clitypes.UserSpaceDetail FileHash clitypes.FileHash } func (b *GraphNodeBuilder) NewBypassFromShardStoreHTTP(userSpace clitypes.UserSpaceDetail, fileHash clitypes.FileHash) *BypassFromShardStoreHTTPNode { node := &BypassFromShardStoreHTTPNode{ UserSpace: userSpace, FileHash: fileHash, } b.AddNode(node) node.OutputValues().Init(node, 1) return node } func (n *BypassFromShardStoreHTTPNode) HTTPRequestVar() dag.ValueOutputSlot { return dag.ValueOutputSlot{ Node: n, Index: 0, } } func (n *BypassFromShardStoreHTTPNode) GenerateOp() (exec.Op, error) { return &BypassFromShardStoreHTTP{ UserSpace: n.UserSpace, FileHash: n.FileHash, Output: n.HTTPRequestVar().Var().VarID, }, nil }