You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

s2s.go 3.8 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. package opt
  2. import (
  3. "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/ioswitch2"
  4. "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/ioswitch2/ops2"
  5. "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/ioswitch2/parser/state"
  6. "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/storage/factory"
  7. )
  8. // 将直接从一个存储服务传到另一个存储服务的过程换成S2S传输
  9. func UseS2STransfer(ctx *state.GenerateState) {
  10. // S2S传输暂不支持只传文件的一部分
  11. if ctx.StreamRange.Offset != 0 || ctx.StreamRange.Length != nil {
  12. return
  13. }
  14. for fr, frNode := range ctx.FromNodes {
  15. switch fr := fr.(type) {
  16. case *ioswitch2.FromShardStore:
  17. s2sFromShardStore(ctx, fr, frNode)
  18. case *ioswitch2.FromBaseStore:
  19. s2sFromBaseStore(ctx, fr, frNode)
  20. }
  21. }
  22. }
  23. func s2sFromShardStore(ctx *state.GenerateState, fromShard *ioswitch2.FromShardStore, frNode ops2.FromNode) {
  24. fromStgBld := factory.GetBuilder(&fromShard.UserSpace)
  25. s2s, err := fromStgBld.CreateS2STransfer(true)
  26. if err != nil {
  27. return
  28. }
  29. // 此输出流的所有目的地都要能支持S2S传输
  30. outVar := frNode.Output().Var()
  31. if outVar.Dst.Len() == 0 {
  32. return
  33. }
  34. failed := false
  35. var toBases []*ops2.BaseWriteNode
  36. loop:
  37. for i := 0; i < outVar.Dst.Len(); i++ {
  38. dstNode := outVar.Dst.Get(i)
  39. switch dstNode := dstNode.(type) {
  40. case *ops2.BaseWriteNode:
  41. if !s2s.CanTransfer(&fromShard.UserSpace, &dstNode.UserSpace) {
  42. failed = true
  43. break
  44. }
  45. toBases = append(toBases, dstNode)
  46. default:
  47. failed = true
  48. break loop
  49. }
  50. }
  51. if failed {
  52. return
  53. }
  54. for _, toBase := range toBases {
  55. s2sNode := ctx.DAG.NewS2STransferDyn(fromShard.UserSpace, toBase.UserSpace, toBase.Path)
  56. // 直传指令在目的地Hub上执行
  57. s2sNode.Env().CopyFrom(toBase.Env())
  58. // 先获取文件路径,送到S2S节点
  59. gsNode := ctx.DAG.NewGetShardInfo(fromShard.UserSpace, fromShard.FileHash)
  60. gsNode.Env().CopyFrom(toBase.Env())
  61. gsNode.FileInfoVar().ToSlot(s2sNode.SrcFileInfoSlot())
  62. // 原本BaseWriteNode的FileInfoVar被替换成S2SNode的FileInfoVar
  63. for _, dstSlot := range toBase.FileInfoVar().ListDstSlots() {
  64. s2sNode.FileInfoVar().ToSlot(dstSlot)
  65. }
  66. // 从计划中删除目标节点
  67. ctx.DAG.RemoveNode(toBase)
  68. delete(ctx.ToNodes, toBase.To)
  69. }
  70. // 从计划中删除源节点
  71. ctx.DAG.RemoveNode(frNode)
  72. delete(ctx.FromNodes, frNode.GetFrom())
  73. }
  74. func s2sFromBaseStore(ctx *state.GenerateState, fromBase *ioswitch2.FromBaseStore, frNode ops2.FromNode) {
  75. fromStgBld := factory.GetBuilder(&fromBase.UserSpace)
  76. s2s, err := fromStgBld.CreateS2STransfer(true)
  77. if err != nil {
  78. return
  79. }
  80. // 此输出流的所有目的地都要能支持S2S传输
  81. outVar := frNode.Output().Var()
  82. if outVar.Dst.Len() == 0 {
  83. return
  84. }
  85. failed := false
  86. var toBases []*ops2.BaseWriteNode
  87. loop:
  88. for i := 0; i < outVar.Dst.Len(); i++ {
  89. dstNode := outVar.Dst.Get(i)
  90. switch dstNode := dstNode.(type) {
  91. case *ops2.BaseWriteNode:
  92. if !s2s.CanTransfer(&fromBase.UserSpace, &dstNode.UserSpace) {
  93. failed = true
  94. break
  95. }
  96. toBases = append(toBases, dstNode)
  97. default:
  98. failed = true
  99. break loop
  100. }
  101. }
  102. if failed {
  103. return
  104. }
  105. for _, toBase := range toBases {
  106. s2sNode := ctx.DAG.NewS2STransfer(fromBase.UserSpace, fromBase.Path, toBase.UserSpace, toBase.Path)
  107. // 直传指令在目的地Hub上执行
  108. s2sNode.Env().CopyFrom(toBase.Env())
  109. // 原本BaseWriteNode的FileInfoVar被替换成S2SNode的FileInfoVar
  110. for _, dstSlot := range toBase.FileInfoVar().ListDstSlots() {
  111. s2sNode.FileInfoVar().ToSlot(dstSlot)
  112. }
  113. // 从计划中删除目标节点
  114. ctx.DAG.RemoveNode(toBase)
  115. delete(ctx.ToNodes, toBase.To)
  116. }
  117. // 从计划中删除源节点
  118. ctx.DAG.RemoveNode(frNode)
  119. delete(ctx.FromNodes, frNode.GetFrom())
  120. }

本项目旨在将云际存储公共基础设施化,使个人及企业可低门槛使用高效的云际存储服务(安装开箱即用云际存储客户端即可,无需关注其他组件的部署),同时支持用户灵活便捷定制云际存储的功能细节。