Commit 7badf3b1 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 9a128aa5
......@@ -32,6 +32,7 @@ import (
"github.com/pkg/errors"
"lab.nexedi.com/kirr/go123/mem"
"lab.nexedi.com/kirr/go123/xcontext"
"lab.nexedi.com/kirr/go123/xerr"
"lab.nexedi.com/kirr/go123/xnet"
"lab.nexedi.com/kirr/go123/xsync"
......@@ -53,7 +54,7 @@ import (
type Client struct {
node *_MasteredNode
// runWG *xsync.WorkGroup
runWG *xsync.WorkGroup
runCancel func()
// driver client <- watcher: database commits | errors.
......@@ -77,10 +78,15 @@ var _ zodb.IStorageDriver = (*Client)(nil)
// It will connect to master @masterAddr and identify with specified cluster name.
// Use Run to actually start running the node.
func NewClient(clusterName, masterAddr string, net xnet.Networker) *Client {
return &Client{
c := &Client{
node: newMasteredNode(proto.CLIENT, clusterName, net, masterAddr),
at0Ready: make(chan struct{}),
}
var runCtx context.Context
runCtx, c.runCancel = context.WithCancel(context.Background())
c.runWG = xsync.NewWorkGroup(runCtx)
return c
}
// Run starts client node and runs it until either ctx is canceled or master
......@@ -89,41 +95,45 @@ func (c *Client) Run(ctx context.Context) (err error) {
// run process which performs master talk
ctx, cancel := context.WithCancel(ctx)
c.runCancel = cancel
// c.node.OnShutdown = cancel // XXX ok?
// return c.talkMaster(ctx)
// c.runWG = xsync.NewWorkGroup(ctx) // XXX create it in NewClient ? (Close also uses it)
// c.runWG.Go(c.node.talkMaster)
// c.runWG.Go(c.recvMaster)
return c.node.TalkMaster(ctx, func(ctx context.Context, mlink *neonet.NodeLink) error {
// XXX errctx ("on redial"? "connected"?)
c.head0 = c.head
c.runWG.Go(func(runCtx context.Context) error {
ctx, cancel := xcontext.Merge(ctx, runCtx) // TODO -> MergeCancel
defer cancel()
wg := xsync.NewWorkGroup(ctx)
return c.node.TalkMaster(ctx, func(ctx context.Context, mlink *neonet.NodeLink) error {
// XXX errctx ("on redial"? "connected"?)
// launch master notifications receiver
wg.Go(func(ctx context.Context) error {
return c.recvMaster(ctx)
})
c.head0 = c.head
// sync lastTid with master
// TODO better change protocol for master to send us head via notify
// channel right after identification.
wg.Go(func(ctx context.Context) error {
return c.syncMaster(ctx, mlink)
})
wg := xsync.NewWorkGroup(ctx)
// launch master notifications receiver
wg.Go(func(ctx context.Context) error {
return c.recvMaster(ctx)
})
return wg.Wait()
// sync lastTid with master
// TODO better change protocol for master to send us head via notify
// channel right after identification.
wg.Go(func(ctx context.Context) error {
return c.syncMaster(ctx, mlink)
})
return wg.Wait()
})
})
// return c.runWG.Wait()
return c.runWG.Wait()
}
// Close implements zodb.IStorageDriver.
func (c *Client) Close() (err error) {
c.runCancel()
// err = c.runWG.Wait() XXX reenable
err = c.runWG.Wait()
if errors.Is(err, context.Canceled) {
err = nil // we canceled it
}
// close networker if configured to do so
if c.ownNet {
......
......@@ -120,7 +120,6 @@ func newMasteredNode(typ proto.NodeType, clusterName string, net xnet.Networker,
},
opReady: make(chan struct{}),
rxm: make(chan _RxM),
}
return node
......@@ -244,11 +243,13 @@ func (node *_MasteredNode) talkMaster1(ctx, ctxPreTalkM context.Context, f func(
wg := xsync.NewWorkGroup(ctx)
// receive and handle notifications from master
node.rxm = make(chan _RxM)
wg.Go(func(ctx context.Context) error {
defer task.Running(&ctx, "rx prefilter")(&err)
for {
req, err := mlink.Recv1()
if err != nil {
close(node.rxm)
return err
}
err = node.recvMaster1(ctx, req) // req ownership is passed in
......@@ -305,13 +306,16 @@ func (node *_MasteredNode) recvMaster1(ctx context.Context, req neonet.Request)
return nil
}
var errMasterDisconect = errors.New("master disconnected")
// RecvM1 receives request from master filtered through δstate handler.
//
// XXX link down ?
// XXX kill err?
// Must be called only when master link is established - e.g. from under TalkMaster.
func (node *_MasteredNode) RecvM1() (neonet.Request, error) {
rx := <-node.rxm
// XXX close -> EOF?
rx, ok := <-node.rxm
if !ok {
return neonet.Request{}, errMasterDisconect
}
return rx.Req, rx.Err
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment