package opt import ( "gitlink.org.cn/cloudream/common/pkgs/ioswitch/dag" "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/ioswitch2/ops2" "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/ioswitch2/parser/state" "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/storage/factory" ) // 将直接从一个存储服务传到另一个存储服务的过程换成S2S传输 func UseS2STransfer(ctx *state.GenerateState) { // S2S传输暂不支持只传文件的一部分 if ctx.StreamRange.Offset != 0 || ctx.StreamRange.Length != nil { return } dag.WalkOnlyType[*ops2.BaseWriteNode](ctx.DAG.Graph, func(node *ops2.BaseWriteNode) bool { inputVar := node.Input().Var() if inputVar == nil { return true } s2s, err := factory.GetBuilder(&node.UserSpace).CreateS2STransfer(true) if err != nil { return true } // 只有BaseRead->BaseWrite的情况才可以进行S2S传输 switch inputNode := inputVar.Src.(type) { case *ops2.BaseReadNode: if !s2s.CanTransfer(&inputNode.UserSpace, &node.UserSpace) { return true } s2sNode := ctx.DAG.NewS2STransfer(inputNode.UserSpace, inputNode.Path, node.UserSpace, node.Path) // 直传指令在目的地Hub上执行 s2sNode.Env().CopyFrom(node.Env()) // 原本BaseWriteNode的FileInfoVar被替换成S2SNode的FileInfoVar for _, dstSlot := range node.FileInfoVar().ListDstSlots() { s2sNode.FileInfoVar().ToSlot(dstSlot) } case *ops2.BaseReadDynNode: if !s2s.CanTransfer(&inputNode.UserSpace, &node.UserSpace) { return true } s2sNode := ctx.DAG.NewS2STransferDyn(inputNode.UserSpace, node.UserSpace, node.Path) // 直传指令在目的地Hub上执行 s2sNode.Env().CopyFrom(node.Env()) // 原本BaseWriteNode的FileInfoVar被替换成S2SNode的FileInfoVar for _, dstSlot := range node.FileInfoVar().ListDstSlots() { s2sNode.FileInfoVar().ToSlot(dstSlot) } // 传递给BaseReadDyn的FileInfo也给S2S一份 srcFileInfoVar := inputNode.FileInfoSlot().Var() if srcFileInfoVar != nil { srcFileInfoVar.ToSlot(s2sNode.SrcFileInfoSlot()) } default: return true } // 中断srcVar的流向 inputVar.NotTo(node) // 从计划中删除目标节点 ctx.DAG.RemoveNode(node) return true }) }