Skip to content

Commit 6a641c7

Browse files
committed
xreg: move xaction startup outside renewal lock (fix)
Renewable.Start runs while holding the registry-wide renewal mutex. * make sure all respective xaction factories do construction only * move initial list-objects throttling into its Run() while preserving the readiness wait * potential behavior change: multi-object (TCO, arch) to fail fast on duplicate transport receiver registration ---- * tests: update unit test `shard_summ_test.go` ---- This was motivated by #336 (lock contention) further leading to an investigation of the Renewable.Start and associated control sequences. Signed-off-by: Alex Aizman <alex.aizman@gmail.com>
1 parent 3c1cb6e commit 6a641c7

14 files changed

Lines changed: 52 additions & 42 deletions

File tree

ais/tgtbck.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,11 @@ func (t *target) bckSumm(w http.ResponseWriter, r *http.Request, phase string, b
501501
t.writeErr(w, r, rns.Err, http.StatusInternalServerError, Silent)
502502
return
503503
}
504+
505+
xctn := rns.Entry.Get()
506+
if !rns.IsRunning() {
507+
xact.GoRunW(xctn)
508+
}
504509
w.WriteHeader(http.StatusAccepted)
505510
return
506511
}
@@ -546,6 +551,11 @@ func (t *target) shardSumm(w http.ResponseWriter, r *http.Request, phase string,
546551
t.writeErr(w, r, rns.Err, http.StatusInternalServerError, Silent)
547552
return
548553
}
554+
555+
xctn := rns.Entry.Get()
556+
if !rns.IsRunning() {
557+
xact.GoRunW(xctn)
558+
}
549559
w.WriteHeader(http.StatusAccepted)
550560
return
551561
}

ais/tgttxn.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,9 @@ func (t *target) tcobjs(c *txnSrv, msg *cmn.TCOMsg, disableDM bool) (xid string,
749749
xctn := rns.Entry.Get()
750750
xid = xctn.ID()
751751

752+
if !rns.IsRunning() {
753+
xact.GoRunW(xctn)
754+
}
752755
xtco := xctn.(*xs.XactTCO)
753756

754757
debug.Assert(msg.TxnUUID == "" || msg.TxnUUID == c.uuid) // (ref050724)
@@ -905,6 +908,10 @@ func (t *target) createArchMultiObj(c *txnSrv) (string /*xaction uuid*/, error)
905908
xctn := rns.Entry.Get()
906909
xid = xctn.ID()
907910

911+
if !rns.IsRunning() {
912+
xact.GoRunW(xctn)
913+
}
914+
908915
xarch := xctn.(*xs.XactArch)
909916
// finalize the message and begin local transaction
910917
archMsg.TxnUUID = c.uuid

ec/getx.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,11 @@ func (*getFactory) New(_ xreg.Args, bck *meta.Bck) xreg.Renewable {
6565
return p
6666
}
6767

68+
// construct apc.ActECGet xaction (EC manager runs it via _renewXact => xact.GoRunW)
6869
func (p *getFactory) Start() error {
6970
xec := ECM.NewGetXact(p.Bck.Bucket())
7071
xec.DemandBase.Init(cos.GenUUID(), p.Kind(), p.Bck, 0 /*use default*/)
7172
p.xctn = xec
72-
73-
xact.GoRunW(xec)
7473
return nil
7574
}
7675
func (*getFactory) Kind() string { return apc.ActECGet }

ec/manager.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,12 @@ func _renewXact(bck *meta.Bck, kind string) (core.Xact, error) {
240240
if rns.Err != nil {
241241
return nil, rns.Err
242242
}
243-
return rns.Entry.Get(), nil
243+
244+
xctn := rns.Entry.Get()
245+
if !rns.IsRunning() {
246+
xact.GoRunW(xctn)
247+
}
248+
return xctn, nil
244249
}
245250

246251
// A function to process command requests from other targets

ec/putx.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,11 @@ func (*putFactory) New(_ xreg.Args, bck *meta.Bck) xreg.Renewable {
6565
return p
6666
}
6767

68+
// construct apc.ActECPut xaction (EC manager runs it via _renewXact => xact.GoRunW)
6869
func (p *putFactory) Start() error {
6970
xec := ECM.NewPutXact(p.Bck.Bucket())
7071
xec.DemandBase.Init(cos.GenUUID(), p.Kind(), p.Bck, 0 /*use default*/)
7172
p.xctn = xec
72-
73-
xact.GoRunW(xec)
7473
return nil
7574
}
7675

ec/respondx.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,11 @@ func (p *rspFactory) WhenPrevIsRunning(xprev xreg.Renewable) (xreg.WPR, error) {
5959
return xreg.WprUse, nil
6060
}
6161

62+
// construct apc.ActECRespond xaction (EC manager runs it via _renewXact => xact.GoRunW)
6263
func (p *rspFactory) Start() error {
6364
xec := ECM.NewRespondXact(p.Bck.Bucket())
6465
xec.DemandBase.Init(cos.GenUUID(), p.Kind(), p.Bck, 0 /*use default*/)
6566
p.xctn = xec
66-
67-
xact.GoRunW(xec)
6867
return nil
6968
}
7069

xact/xreg/xreg.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,18 @@ const (
5656

5757
type (
5858
Renewable interface {
59-
New(args Args, bck *meta.Bck) Renewable // new xaction stub that can be `Start`-ed; TODO ref: New(args, bck, kind)
60-
Start() error // starts an xaction, will be called when entry is stored into registry
59+
New(args Args, bck *meta.Bck) Renewable
6160
Kind() string
6261
Get() core.Xact
6362
WhenPrevIsRunning(prevEntry Renewable) (action WPR, err error)
6463
Bucket() *meta.Bck
6564
UUID() string
65+
66+
// NOTE:
67+
// Start constructs and initializes the xaction while holding the registry-wide renewMtx.
68+
// It must not wait, sleep, perform blocking channel operations, or call xact.GoRunW.
69+
// The renewal caller starts a newly constructed xaction after Renew returns.
70+
Start() error
6671
}
6772
// used in constructions
6873
Args struct {

xact/xs/archive.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ func (*archFactory) New(args xreg.Args, bck *meta.Bck) xreg.Renewable {
108108
return p
109109
}
110110

111+
// construct, initialize xact.Demand (and reg w/ HK), open streams
112+
// (the renewal caller does xact.GoRunW)
111113
func (p *archFactory) Start() (err error) {
112114
//
113115
// target-local generation of a global UUID
@@ -150,8 +152,6 @@ func (p *archFactory) Start() (err error) {
150152
}
151153
}
152154
r.sntl.init(r, r.p.dm, r.config, r.smap, nat)
153-
154-
xact.GoRunW(r)
155155
return nil
156156
}
157157

xact/xs/lso.go

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -210,11 +210,6 @@ func (p *lsoFactory) Start() error {
210210
RW: false,
211211
},
212212
)
213-
// and maybe throttle right away
214-
if r.adv.Sleep > 0 {
215-
time.Sleep(r.adv.Sleep)
216-
}
217-
218213
_ = r.CtlMsg()
219214
r.vlabs = map[string]string{stats.VlabBucket: bck.Cname("")}
220215
p.xctn = r
@@ -317,6 +312,9 @@ func (r *LsoXact) CtlMsg() string {
317312
}
318313

319314
func (r *LsoXact) Run(wg *sync.WaitGroup) {
315+
if r.adv.Sleep > 0 {
316+
time.Sleep(r.adv.Sleep)
317+
}
320318
wg.Done()
321319

322320
if !r.walk.remote {

xact/xs/nsumm.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,9 @@ func (*nsummFactory) New(args xreg.Args, bck *meta.Bck) xreg.Renewable {
6464
return p
6565
}
6666

67+
// construction only (the renewal caller does xact.GoRunW)
6768
func (p *nsummFactory) Start() (err error) {
6869
p.xctn, err = newSumm(p)
69-
if err == nil {
70-
xact.GoRunW(p.xctn)
71-
}
7270
return
7371
}
7472

0 commit comments

Comments
 (0)