| @@ -11,6 +11,7 @@ require ( | |||||
| github.com/json-iterator/go v1.1.12 | github.com/json-iterator/go v1.1.12 | ||||
| github.com/magefile/mage v1.15.0 | github.com/magefile/mage v1.15.0 | ||||
| github.com/mitchellh/mapstructure v1.5.0 | github.com/mitchellh/mapstructure v1.5.0 | ||||
| github.com/modern-go/reflect2 v1.0.2 | |||||
| github.com/otiai10/copy v1.12.0 | github.com/otiai10/copy v1.12.0 | ||||
| github.com/samber/lo v1.36.0 | github.com/samber/lo v1.36.0 | ||||
| github.com/sirupsen/logrus v1.9.2 | github.com/sirupsen/logrus v1.9.2 | ||||
| @@ -41,7 +42,6 @@ require ( | |||||
| github.com/minio/sha256-simd v1.0.0 // indirect | github.com/minio/sha256-simd v1.0.0 // indirect | ||||
| github.com/mitchellh/go-homedir v1.1.0 // indirect | github.com/mitchellh/go-homedir v1.1.0 // indirect | ||||
| github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect | ||||
| github.com/modern-go/reflect2 v1.0.2 // indirect | |||||
| github.com/mr-tron/base58 v1.2.0 // indirect | github.com/mr-tron/base58 v1.2.0 // indirect | ||||
| github.com/multiformats/go-base32 v0.1.0 // indirect | github.com/multiformats/go-base32 v0.1.0 // indirect | ||||
| github.com/multiformats/go-base36 v0.2.0 // indirect | github.com/multiformats/go-base36 v0.2.0 // indirect | ||||
| @@ -8,7 +8,7 @@ import ( | |||||
| "github.com/zyedidia/generic/list" | "github.com/zyedidia/generic/list" | ||||
| "gitlink.org.cn/cloudream/common/pkgs/future" | "gitlink.org.cn/cloudream/common/pkgs/future" | ||||
| mysync "gitlink.org.cn/cloudream/common/utils/sync" | |||||
| "gitlink.org.cn/cloudream/common/utils/sync2" | |||||
| ) | ) | ||||
| type CommandFn func() | type CommandFn func() | ||||
| @@ -16,7 +16,7 @@ type CommandFn func() | |||||
| type CommandChannel struct { | type CommandChannel struct { | ||||
| cmds *list.List[CommandFn] | cmds *list.List[CommandFn] | ||||
| cmdsLock sync.Mutex | cmdsLock sync.Mutex | ||||
| cmdsCounter *mysync.CounterCond | |||||
| cmdsCounter *sync2.CounterCond | |||||
| chanReceive chan CommandFn | chanReceive chan CommandFn | ||||
| chanReceiveDone atomic.Bool | chanReceiveDone atomic.Bool | ||||
| @@ -28,7 +28,7 @@ type CommandChannel struct { | |||||
| func NewCommandChannel() *CommandChannel { | func NewCommandChannel() *CommandChannel { | ||||
| return &CommandChannel{ | return &CommandChannel{ | ||||
| cmds: list.New[CommandFn](), | cmds: list.New[CommandFn](), | ||||
| cmdsCounter: mysync.NewCounterCond(0), | |||||
| cmdsCounter: sync2.NewCounterCond(0), | |||||
| cmdChan: make(chan CommandFn), | cmdChan: make(chan CommandFn), | ||||
| } | } | ||||
| } | } | ||||
| @@ -4,7 +4,7 @@ import ( | |||||
| "sync" | "sync" | ||||
| "github.com/zyedidia/generic/list" | "github.com/zyedidia/generic/list" | ||||
| mysync "gitlink.org.cn/cloudream/common/utils/sync" | |||||
| "gitlink.org.cn/cloudream/common/utils/sync2" | |||||
| ) | ) | ||||
| type ExecuteOption struct { | type ExecuteOption struct { | ||||
| @@ -26,7 +26,7 @@ type postedEvent[TArgs any] struct { | |||||
| type Executor[TArgs any] struct { | type Executor[TArgs any] struct { | ||||
| events *list.List[postedEvent[TArgs]] | events *list.List[postedEvent[TArgs]] | ||||
| locker sync.Mutex | locker sync.Mutex | ||||
| eventCond *mysync.CounterCond | |||||
| eventCond *sync2.CounterCond | |||||
| execArgs TArgs | execArgs TArgs | ||||
| } | } | ||||
| @@ -34,7 +34,7 @@ func NewExecutor[TArgs any](args TArgs) Executor[TArgs] { | |||||
| return Executor[TArgs]{ | return Executor[TArgs]{ | ||||
| events: list.New[postedEvent[TArgs]](), | events: list.New[postedEvent[TArgs]](), | ||||
| locker: sync.Mutex{}, | locker: sync.Mutex{}, | ||||
| eventCond: mysync.NewCounterCond(0), | |||||
| eventCond: sync2.NewCounterCond(0), | |||||
| execArgs: args, | execArgs: args, | ||||
| } | } | ||||
| @@ -6,12 +6,12 @@ import ( | |||||
| "io" | "io" | ||||
| shell "github.com/ipfs/go-ipfs-api" | shell "github.com/ipfs/go-ipfs-api" | ||||
| myio "gitlink.org.cn/cloudream/common/utils/io" | |||||
| "gitlink.org.cn/cloudream/common/utils/io2" | |||||
| ) | ) | ||||
| type ReadOption struct { | type ReadOption struct { | ||||
| Offset int64 // 从指定位置开始读取,为-1时代表不设置,从头开始读 | |||||
| Length int64 // 读取长度,为-1时代表不设置,读取Offset之后的所有内容 | |||||
| Offset int64 `json:"offset,string"` // 从指定位置开始读取,为-1时代表不设置,从头开始读 | |||||
| Length int64 `json:"length,string"` // 读取长度,为-1时代表不设置,读取Offset之后的所有内容 | |||||
| } | } | ||||
| type Client struct { | type Client struct { | ||||
| @@ -35,7 +35,7 @@ func (fs *Client) IsUp() bool { | |||||
| return fs.shell.IsUp() | return fs.shell.IsUp() | ||||
| } | } | ||||
| func (fs *Client) CreateFileStream() (myio.PromiseWriteCloser[string], error) { | |||||
| func (fs *Client) CreateFileStream() (io2.PromiseWriteCloser[string], error) { | |||||
| pr, pw := io.Pipe() | pr, pw := io.Pipe() | ||||
| ipfsWriter := ipfsWriter{ | ipfsWriter := ipfsWriter{ | ||||
| @@ -0,0 +1,18 @@ | |||||
| package iterator | |||||
| type fuseError[T any] struct { | |||||
| err error | |||||
| } | |||||
| func (i *fuseError[T]) MoveNext() (T, error) { | |||||
| var ret T | |||||
| return ret, i.err | |||||
| } | |||||
| func (i *fuseError[T]) Close() { | |||||
| } | |||||
| func FuseError[T any](err error) Iterator[T] { | |||||
| return &fuseError[T]{ | |||||
| err: err, | |||||
| } | |||||
| } | |||||
| @@ -100,6 +100,8 @@ const ObjectDownloadPath = "/object/download" | |||||
| type ObjectDownload struct { | type ObjectDownload struct { | ||||
| UserID UserID `form:"userID" json:"userID" binding:"required"` | UserID UserID `form:"userID" json:"userID" binding:"required"` | ||||
| ObjectID ObjectID `form:"objectID" json:"objectID" binding:"required"` | ObjectID ObjectID `form:"objectID" json:"objectID" binding:"required"` | ||||
| Offset int64 `form:"offset" json:"offset"` | |||||
| Length *int64 `form:"length" json:"length"` | |||||
| } | } | ||||
| type DownloadingObject struct { | type DownloadingObject struct { | ||||
| Path string | Path string | ||||
| @@ -8,7 +8,7 @@ import ( | |||||
| "strings" | "strings" | ||||
| myhttp "gitlink.org.cn/cloudream/common/utils/http" | myhttp "gitlink.org.cn/cloudream/common/utils/http" | ||||
| "gitlink.org.cn/cloudream/common/utils/math" | |||||
| "gitlink.org.cn/cloudream/common/utils/math2" | |||||
| "gitlink.org.cn/cloudream/common/utils/serder" | "gitlink.org.cn/cloudream/common/utils/serder" | ||||
| ) | ) | ||||
| @@ -34,5 +34,5 @@ func ParseJSONResponse[TBody any](resp *http.Response) (TBody, error) { | |||||
| } | } | ||||
| strCont := string(cont) | strCont := string(cont) | ||||
| return ret, fmt.Errorf("unknow response content type: %s, status: %d, body(prefix): %s", contType, resp.StatusCode, strCont[:math.Min(len(strCont), 200)]) | |||||
| return ret, fmt.Errorf("unknow response content type: %s, status: %d, body(prefix): %s", contType, resp.StatusCode, strCont[:math2.Min(len(strCont), 200)]) | |||||
| } | } | ||||
| @@ -7,11 +7,12 @@ import ( | |||||
| "mime" | "mime" | ||||
| "mime/multipart" | "mime/multipart" | ||||
| "net/http" | "net/http" | ||||
| "net/textproto" | |||||
| ul "net/url" | ul "net/url" | ||||
| "strings" | "strings" | ||||
| "gitlink.org.cn/cloudream/common/pkgs/iterator" | "gitlink.org.cn/cloudream/common/pkgs/iterator" | ||||
| "gitlink.org.cn/cloudream/common/utils/math" | |||||
| "gitlink.org.cn/cloudream/common/utils/math2" | |||||
| "gitlink.org.cn/cloudream/common/utils/serder" | "gitlink.org.cn/cloudream/common/utils/serder" | ||||
| ) | ) | ||||
| @@ -129,13 +130,14 @@ func ParseJSONResponse[TBody any](resp *http.Response) (TBody, error) { | |||||
| } | } | ||||
| strCont := string(cont) | strCont := string(cont) | ||||
| return ret, fmt.Errorf("unknow response content type: %s, status: %d, body(prefix): %s", contType, resp.StatusCode, strCont[:math.Min(len(strCont), 200)]) | |||||
| return ret, fmt.Errorf("unknow response content type: %s, status: %d, body(prefix): %s", contType, resp.StatusCode, strCont[:math2.Min(len(strCont), 200)]) | |||||
| } | } | ||||
| type MultiPartFile struct { | type MultiPartFile struct { | ||||
| FieldName string | FieldName string | ||||
| FileName string | FileName string | ||||
| File io.ReadCloser | File io.ReadCloser | ||||
| Header textproto.MIMEHeader | |||||
| } | } | ||||
| type multiPartFileIterator struct { | type multiPartFileIterator struct { | ||||
| @@ -157,6 +159,7 @@ func (m *multiPartFileIterator) MoveNext() (*MultiPartFile, error) { | |||||
| FieldName: f.FormName(), | FieldName: f.FormName(), | ||||
| FileName: fileName, | FileName: fileName, | ||||
| File: f, | File: f, | ||||
| Header: f.Header, | |||||
| }, nil | }, nil | ||||
| } | } | ||||
| @@ -179,6 +182,7 @@ func (m *multiPartFileIterator) MoveNext() (*MultiPartFile, error) { | |||||
| FieldName: part.FormName(), | FieldName: part.FormName(), | ||||
| FileName: fileName, | FileName: fileName, | ||||
| File: part, | File: part, | ||||
| Header: part.Header, | |||||
| }, nil | }, nil | ||||
| } | } | ||||
| } | } | ||||
| @@ -1,4 +1,4 @@ | |||||
| package io | |||||
| package io2 | |||||
| import ( | import ( | ||||
| "bufio" | "bufio" | ||||
| @@ -1,4 +1,4 @@ | |||||
| package io | |||||
| package io2 | |||||
| import ( | import ( | ||||
| "fmt" | "fmt" | ||||
| @@ -1,4 +1,4 @@ | |||||
| package io | |||||
| package io2 | |||||
| import ( | import ( | ||||
| "bytes" | "bytes" | ||||
| @@ -1,4 +1,4 @@ | |||||
| package io | |||||
| package io2 | |||||
| import ( | import ( | ||||
| "io" | "io" | ||||
| @@ -1,4 +1,4 @@ | |||||
| package io | |||||
| package io2 | |||||
| import "io" | import "io" | ||||
| @@ -1,4 +1,4 @@ | |||||
| package io | |||||
| package io2 | |||||
| import ( | import ( | ||||
| "bytes" | "bytes" | ||||
| @@ -1,10 +1,10 @@ | |||||
| package io | |||||
| package io2 | |||||
| import ( | import ( | ||||
| "io" | "io" | ||||
| "gitlink.org.cn/cloudream/common/utils/lo2" | "gitlink.org.cn/cloudream/common/utils/lo2" | ||||
| "gitlink.org.cn/cloudream/common/utils/math" | |||||
| "gitlink.org.cn/cloudream/common/utils/math2" | |||||
| ) | ) | ||||
| func Join(strs []io.Reader) io.ReadCloser { | func Join(strs []io.Reader) io.ReadCloser { | ||||
| @@ -69,7 +69,7 @@ func (s *chunkedJoin) Read(buf []byte) (int, error) { | |||||
| return 0, io.EOF | return 0, io.EOF | ||||
| } | } | ||||
| bufLen := math.Min(math.Min(s.chunkSize, len(buf)), s.chunkSize-s.currentRead) | |||||
| bufLen := math2.Min(math2.Min(s.chunkSize, len(buf)), s.chunkSize-s.currentRead) | |||||
| rd, err := s.inputs[s.currentInput].Read(buf[:bufLen]) | rd, err := s.inputs[s.currentInput].Read(buf[:bufLen]) | ||||
| if err == nil { | if err == nil { | ||||
| s.currentRead += rd | s.currentRead += rd | ||||
| @@ -1,9 +1,9 @@ | |||||
| package io | |||||
| package io2 | |||||
| import ( | import ( | ||||
| "io" | "io" | ||||
| "gitlink.org.cn/cloudream/common/utils/math" | |||||
| "gitlink.org.cn/cloudream/common/utils/math2" | |||||
| ) | ) | ||||
| type lengthStream struct { | type lengthStream struct { | ||||
| @@ -19,7 +19,7 @@ func (s *lengthStream) Read(buf []byte) (int, error) { | |||||
| return 0, s.err | return 0, s.err | ||||
| } | } | ||||
| bufLen := math.Min(s.length-s.readLength, int64(len(buf))) | |||||
| bufLen := math2.Min(s.length-s.readLength, int64(len(buf))) | |||||
| rd, err := s.src.Read(buf[:bufLen]) | rd, err := s.src.Read(buf[:bufLen]) | ||||
| if err == nil { | if err == nil { | ||||
| s.readLength += int64(rd) | s.readLength += int64(rd) | ||||
| @@ -1,4 +1,4 @@ | |||||
| package io | |||||
| package io2 | |||||
| import "io" | import "io" | ||||
| @@ -1,4 +1,4 @@ | |||||
| package math | |||||
| package math2 | |||||
| import "golang.org/x/exp/constraints" | import "golang.org/x/exp/constraints" | ||||
| @@ -1,4 +1,4 @@ | |||||
| package sync | |||||
| package sync2 | |||||
| import "sync" | import "sync" | ||||
| @@ -0,0 +1,20 @@ | |||||
| package sync2 | |||||
| import "sync" | |||||
| func ParallelDo[T any](args []T, fn func(val T, index int) error) error { | |||||
| var err error | |||||
| var wg sync.WaitGroup | |||||
| wg.Add(len(args)) | |||||
| for i, arg := range args { | |||||
| go func(arg T, index int) { | |||||
| defer wg.Done() | |||||
| if e := fn(arg, index); e != nil { | |||||
| err = e | |||||
| } | |||||
| }(arg, i) | |||||
| } | |||||
| wg.Wait() | |||||
| return err | |||||
| } | |||||