Browse Source

实现PubLock的RPC接口

master
Sydonian 3 months ago
parent
commit
17e4452435
10 changed files with 142 additions and 30 deletions
  1. +26
    -0
      client/internal/cmdline/serve.go
  2. +2
    -0
      client/internal/config/config.go
  3. +1
    -9
      client/internal/publock/core.go
  4. +13
    -4
      client/internal/publock/mutex.go
  5. +12
    -3
      client/internal/publock/reentrant.go
  6. +8
    -13
      client/internal/publock/service.go
  7. +2
    -1
      client/internal/publock/types/channel.go
  8. +6
    -0
      client/internal/publock/types/models.go
  9. +54
    -0
      client/internal/rpc/publock.go
  10. +18
    -0
      client/internal/rpc/rpc.go

+ 26
- 0
client/internal/cmdline/serve.go View File

@@ -17,6 +17,7 @@ import (
"gitlink.org.cn/cloudream/jcs-pub/client/internal/metacache" "gitlink.org.cn/cloudream/jcs-pub/client/internal/metacache"
"gitlink.org.cn/cloudream/jcs-pub/client/internal/mount" "gitlink.org.cn/cloudream/jcs-pub/client/internal/mount"
"gitlink.org.cn/cloudream/jcs-pub/client/internal/publock" "gitlink.org.cn/cloudream/jcs-pub/client/internal/publock"
myrpc "gitlink.org.cn/cloudream/jcs-pub/client/internal/rpc"
"gitlink.org.cn/cloudream/jcs-pub/client/internal/services" "gitlink.org.cn/cloudream/jcs-pub/client/internal/services"
"gitlink.org.cn/cloudream/jcs-pub/client/internal/spacesyncer" "gitlink.org.cn/cloudream/jcs-pub/client/internal/spacesyncer"
"gitlink.org.cn/cloudream/jcs-pub/client/internal/speedstats" "gitlink.org.cn/cloudream/jcs-pub/client/internal/speedstats"
@@ -24,6 +25,8 @@ import (
"gitlink.org.cn/cloudream/jcs-pub/client/internal/uploader" "gitlink.org.cn/cloudream/jcs-pub/client/internal/uploader"
stgglb "gitlink.org.cn/cloudream/jcs-pub/common/globals" stgglb "gitlink.org.cn/cloudream/jcs-pub/common/globals"
"gitlink.org.cn/cloudream/jcs-pub/common/pkgs/connectivity" "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/connectivity"
"gitlink.org.cn/cloudream/jcs-pub/common/pkgs/rpc"
clirpc "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/rpc/client"
"gitlink.org.cn/cloudream/jcs-pub/common/pkgs/storage/pool" "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/storage/pool"
"gitlink.org.cn/cloudream/jcs-pub/common/pkgs/sysevent" "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/sysevent"
jcstypes "gitlink.org.cn/cloudream/jcs-pub/common/types" jcstypes "gitlink.org.cn/cloudream/jcs-pub/common/types"
@@ -240,6 +243,11 @@ func serveHTTP(configPath string, opts serveHTTPOptions) {
httpChan := httpSvr.Start() httpChan := httpSvr.Start()
defer httpSvr.Stop() defer httpSvr.Stop()


// RPC接口
rpcSvr := clirpc.NewServer(config.Cfg().RPC, myrpc.NewService(publock), nil)
rpcChan := rpcSvr.Start()
defer rpcSvr.Stop()

/// 开始监听各个模块的事件 /// 开始监听各个模块的事件


accTokenEvt := accTokenChan.Receive() accTokenEvt := accTokenChan.Receive()
@@ -249,6 +257,7 @@ func serveHTTP(configPath string, opts serveHTTPOptions) {
spaceSyncEvt := spaceSyncChan.Receive() spaceSyncEvt := spaceSyncChan.Receive()
// replEvt := replCh.Receive() // replEvt := replCh.Receive()
httpEvt := httpChan.Receive() httpEvt := httpChan.Receive()
rpcEvt := rpcChan.Receive()
mntEvt := mntChan.Receive() mntEvt := mntChan.Receive()


loop: loop:
@@ -358,6 +367,23 @@ loop:
} }
httpEvt = httpChan.Receive() httpEvt = httpChan.Receive()


case e := <-rpcEvt.Chan():
if e.Err != nil {
logger.Errorf("receive rpc event: %v", err)
break loop
}

switch e := e.Value.(type) {
case rpc.ExitEvent:
if e.Err != nil {
logger.Errorf("rpc server exited with error: %v", e.Err)
} else {
logger.Infof("rpc server exited")
}
break loop
}
rpcEvt = rpcChan.Receive()

case e := <-mntEvt.Chan(): case e := <-mntEvt.Chan():
if e.Err != nil { if e.Err != nil {
logger.Errorf("receive mount event: %v", e.Err) logger.Errorf("receive mount event: %v", e.Err)


+ 2
- 0
client/internal/config/config.go View File

@@ -12,6 +12,7 @@ import (
"gitlink.org.cn/cloudream/jcs-pub/client/internal/ticktock" "gitlink.org.cn/cloudream/jcs-pub/client/internal/ticktock"
stgglb "gitlink.org.cn/cloudream/jcs-pub/common/globals" stgglb "gitlink.org.cn/cloudream/jcs-pub/common/globals"
"gitlink.org.cn/cloudream/jcs-pub/common/pkgs/connectivity" "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/connectivity"
"gitlink.org.cn/cloudream/jcs-pub/common/pkgs/rpc"
corrpc "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/rpc/coordinator" corrpc "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/rpc/coordinator"
hubrpc "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/rpc/hub" hubrpc "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/rpc/hub"
"gitlink.org.cn/cloudream/jcs-pub/common/pkgs/sysevent" "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/sysevent"
@@ -29,6 +30,7 @@ type Config struct {
DownloadStrategy strategy.Config `json:"downloadStrategy"` DownloadStrategy strategy.Config `json:"downloadStrategy"`
TickTock ticktock.Config `json:"tickTock"` TickTock ticktock.Config `json:"tickTock"`
HTTP *http.ConfigJSON `json:"http"` HTTP *http.ConfigJSON `json:"http"`
RPC rpc.Config `json:"rpc"`
Mount *mntcfg.Config `json:"mount"` Mount *mntcfg.Config `json:"mount"`
AccessToken *accesstoken.Config `json:"accessToken"` AccessToken *accesstoken.Config `json:"accessToken"`
} }


+ 1
- 9
client/internal/publock/core.go View File

@@ -4,7 +4,6 @@ import (
"context" "context"
"fmt" "fmt"
"sync" "sync"
"time"


"gitlink.org.cn/cloudream/common/pkgs/future" "gitlink.org.cn/cloudream/common/pkgs/future"
"gitlink.org.cn/cloudream/common/pkgs/trie" "gitlink.org.cn/cloudream/common/pkgs/trie"
@@ -47,14 +46,7 @@ type acquireInfo struct {
LastErr error LastErr error
} }


func (svc *Core) Acquire(req types.LockRequest, opts ...AcquireOptionFn) (LockedRequest, error) {
var opt = AcquireOption{
Timeout: time.Second * 10,
}
for _, fn := range opts {
fn(&opt)
}

func (svc *Core) Acquire(req types.LockRequest, opt types.AcquireOption) (LockedRequest, error) {
ctx := context.Background() ctx := context.Background()
if opt.Timeout != 0 { if opt.Timeout != 0 {
var cancel func() var cancel func()


+ 13
- 4
client/internal/publock/mutex.go View File

@@ -1,6 +1,8 @@
package publock package publock


import ( import (
"time"

"gitlink.org.cn/cloudream/jcs-pub/client/internal/publock/reqbuilder" "gitlink.org.cn/cloudream/jcs-pub/client/internal/publock/reqbuilder"
"gitlink.org.cn/cloudream/jcs-pub/client/internal/publock/types" "gitlink.org.cn/cloudream/jcs-pub/client/internal/publock/types"
) )
@@ -11,7 +13,7 @@ type Mutex struct {
} }


func (m *Mutex) Unlock() { func (m *Mutex) Unlock() {
m.pub.release(m.locked.ReqID)
m.pub.Release(m.locked.ReqID)
} }


type MutexBuilder struct { type MutexBuilder struct {
@@ -19,10 +21,17 @@ type MutexBuilder struct {
pub *PubLock pub *PubLock
} }


func (b *MutexBuilder) Lock(opt ...AcquireOptionFn) (*Mutex, error) {
lkd, err := b.pub.acquire(types.LockRequest{
func (b *MutexBuilder) Lock(opts ...AcquireOptionFn) (*Mutex, error) {
var opt = types.AcquireOption{
Timeout: time.Second * 10,
}
for _, fn := range opts {
fn(&opt)
}

lkd, err := b.pub.Acquire(types.LockRequest{
Locks: b.Locks, Locks: b.Locks,
}, opt...)
}, opt)
if err != nil { if err != nil {
return nil, err return nil, err
} }


+ 12
- 3
client/internal/publock/reentrant.go View File

@@ -1,6 +1,8 @@
package publock package publock


import ( import (
"time"

"gitlink.org.cn/cloudream/jcs-pub/client/internal/publock/reqbuilder" "gitlink.org.cn/cloudream/jcs-pub/client/internal/publock/reqbuilder"
"gitlink.org.cn/cloudream/jcs-pub/client/internal/publock/types" "gitlink.org.cn/cloudream/jcs-pub/client/internal/publock/types"
) )
@@ -12,7 +14,14 @@ type Reentrant struct {
locked []LockedRequest locked []LockedRequest
} }


func (r *Reentrant) Lock(opt ...AcquireOptionFn) error {
func (r *Reentrant) Lock(opts ...AcquireOptionFn) error {
var opt = types.AcquireOption{
Timeout: time.Second * 10,
}
for _, fn := range opts {
fn(&opt)
}

var willLock []types.Lock var willLock []types.Lock


loop: loop:
@@ -37,7 +46,7 @@ loop:
Locks: willLock, Locks: willLock,
} }


m, err := r.p.acquire(newReq, opt...)
m, err := r.p.Acquire(newReq, opt)
if err != nil { if err != nil {
return err return err
} }
@@ -50,7 +59,7 @@ loop:


func (r *Reentrant) Unlock() { func (r *Reentrant) Unlock() {
for i := len(r.reqs) - 1; i >= 0; i-- { for i := len(r.reqs) - 1; i >= 0; i-- {
r.p.release(r.locked[i].ReqID)
r.p.Release(r.locked[i].ReqID)
} }
r.locked = nil r.locked = nil
r.reqs = nil r.reqs = nil


+ 8
- 13
client/internal/publock/service.go View File

@@ -12,21 +12,16 @@ import (
clirpc "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/rpc/client" clirpc "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/rpc/client"
) )


type AcquireOption struct {
Timeout time.Duration
Reason string
}

type AcquireOptionFn func(opt *AcquireOption)
type AcquireOptionFn func(opt *types.AcquireOption)


func WithTimeout(timeout time.Duration) AcquireOptionFn { func WithTimeout(timeout time.Duration) AcquireOptionFn {
return func(opt *AcquireOption) {
return func(opt *types.AcquireOption) {
opt.Timeout = timeout opt.Timeout = timeout
} }
} }


func WithReason(reason string) AcquireOptionFn { func WithReason(reason string) AcquireOptionFn {
return func(opt *AcquireOption) {
return func(opt *types.AcquireOption) {
opt.Reason = reason opt.Reason = reason
} }
} }
@@ -97,12 +92,12 @@ func (p *PubLock) Stop() {
p.cliCli = nil p.cliCli = nil
} }


func (p *PubLock) acquire(req types.LockRequest, opts ...AcquireOptionFn) (LockedRequest, error) {
func (p *PubLock) Acquire(req types.LockRequest, opt types.AcquireOption) (LockedRequest, error) {
p.lock.Lock() p.lock.Lock()


if p.core != nil { if p.core != nil {
p.lock.Unlock() p.lock.Unlock()
return p.core.Acquire(req, opts...)
return p.core.Acquire(req, opt)
} }


if p.pubChan == nil { if p.pubChan == nil {
@@ -113,7 +108,7 @@ func (p *PubLock) acquire(req types.LockRequest, opts ...AcquireOptionFn) (Locke
acqID := fmt.Sprintf("%v", p.nextCtxID) acqID := fmt.Sprintf("%v", p.nextCtxID)
p.nextCtxID++ p.nextCtxID++


cerr := p.pubChan.Send(&types.AcquireMsg{ContextID: acqID, Request: req})
cerr := p.pubChan.Send(&types.AcquireMsg{ContextID: acqID, Request: req, Option: opt})
if cerr != nil { if cerr != nil {
p.lock.Unlock() p.lock.Unlock()
return LockedRequest{}, cerr.ToError() return LockedRequest{}, cerr.ToError()
@@ -138,7 +133,7 @@ func (p *PubLock) acquire(req types.LockRequest, opts ...AcquireOptionFn) (Locke
}, nil }, nil
} }


func (p *PubLock) release(reqID types.RequestID) {
func (p *PubLock) Release(reqID types.RequestID) {
log := logger.WithField("Mod", "PubLock") log := logger.WithField("Mod", "PubLock")


p.lock.Lock() p.lock.Lock()
@@ -214,7 +209,7 @@ func (p *PubLock) receivingChan() {
if msg.Success { if msg.Success {
info.Callback.SetValue(msg.RequestID) info.Callback.SetValue(msg.RequestID)
} else { } else {
info.Callback.SetError(fmt.Errorf(msg.Reason))
info.Callback.SetError(fmt.Errorf(msg.Error))
} }
delete(p.acquirings, msg.ContextID) delete(p.acquirings, msg.ContextID)




+ 2
- 1
client/internal/publock/types/channel.go View File

@@ -3,6 +3,7 @@ package types
type AcquireMsg struct { type AcquireMsg struct {
ContextID string ContextID string
Request LockRequest Request LockRequest
Option AcquireOption
} }


func (*AcquireMsg) IsPubLockMessage() bool { return true } func (*AcquireMsg) IsPubLockMessage() bool { return true }
@@ -10,7 +11,7 @@ func (*AcquireMsg) IsPubLockMessage() bool { return true }
type AcquireResultMsg struct { type AcquireResultMsg struct {
ContextID string ContextID string
Success bool Success bool
Reason string
Error string
RequestID RequestID RequestID RequestID
} }




+ 6
- 0
client/internal/publock/types/models.go View File

@@ -2,6 +2,7 @@ package types


import ( import (
"fmt" "fmt"
"time"


"gitlink.org.cn/cloudream/common/utils/lo2" "gitlink.org.cn/cloudream/common/utils/lo2"
) )
@@ -58,3 +59,8 @@ func NewLockTargetBusyError(lockName string) *LockTargetBusyError {
lockName: lockName, lockName: lockName,
} }
} }

type AcquireOption struct {
Timeout time.Duration
Reason string
}

+ 54
- 0
client/internal/rpc/publock.go View File

@@ -0,0 +1,54 @@
package rpc

import (
"gitlink.org.cn/cloudream/common/pkgs/logger"
"gitlink.org.cn/cloudream/jcs-pub/client/internal/publock/types"
clirpc "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/rpc/client"
)

func (s *Service) PubLockChannel(ch clirpc.PubLockMessageChan) {
log := logger.WithField("Mod", "RPC")

for {
msg, cerr := ch.Receive()
if cerr != nil {
log.Warnf("receive publock message: %v", cerr.ToError())
break
}

switch msg := msg.(type) {
case *types.AcquireMsg:
go func() {
lkd, err := s.pubLock.Acquire(msg.Request, msg.Option)
if err != nil {
cerr := ch.Send(&types.AcquireResultMsg{
ContextID: msg.ContextID,
Success: false,
Error: err.Error(),
})
if cerr != nil {
log.Warnf("send acquire result message: %v", cerr.ToError())
}
return
}

cerr := ch.Send(&types.AcquireResultMsg{
ContextID: msg.ContextID,
Success: true,
RequestID: lkd.ReqID,
})
if cerr != nil {
log.Warnf("send acquire result message: %v", cerr.ToError())
}
}()
case *types.ReleaseMsg:
s.pubLock.Release(msg.RequestID)
cerr := ch.Send(&types.ReleaseResultMsg{
ContextID: msg.ContextID,
})
if cerr != nil {
log.Warnf("send release result message: %v", cerr.ToError())
}
}
}
}

+ 18
- 0
client/internal/rpc/rpc.go View File

@@ -0,0 +1,18 @@
package rpc

import (
"gitlink.org.cn/cloudream/jcs-pub/client/internal/publock"
clirpc "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/rpc/client"
)

type Service struct {
pubLock *publock.PubLock
}

func NewService(pubLock *publock.PubLock) *Service {
return &Service{
pubLock: pubLock,
}
}

var _ clirpc.ClientAPI = (*Service)(nil)

Loading…
Cancel
Save