-
Notifications
You must be signed in to change notification settings - Fork 26
[WIP] remove waitpub, export publish #47
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,11 +18,9 @@ type Republisher struct { | |
TimeoutShort time.Duration | ||
valueHasBeenUpdated chan struct{} | ||
pubfunc PubFunc | ||
immediatePublish chan chan struct{} | ||
|
||
valueLock sync.Mutex | ||
valueToPublish cid.Cid | ||
lastValuePublished cid.Cid | ||
valueToPublish *cid.Cid | ||
|
||
ctx context.Context | ||
cancel func() | ||
|
@@ -37,29 +35,13 @@ func NewRepublisher(ctx context.Context, pf PubFunc, tshort, tlong time.Duration | |
TimeoutLong: tlong, | ||
valueHasBeenUpdated: make(chan struct{}, 1), | ||
pubfunc: pf, | ||
immediatePublish: make(chan chan struct{}), | ||
ctx: ctx, | ||
cancel: cancel, | ||
} | ||
} | ||
|
||
// WaitPub waits for the current value to be published (or returns early | ||
// if it already has). | ||
func (rp *Republisher) WaitPub() { | ||
rp.valueLock.Lock() | ||
valueHasBeenPublished := rp.lastValuePublished == rp.valueToPublish | ||
rp.valueLock.Unlock() | ||
if valueHasBeenPublished { | ||
return | ||
} | ||
|
||
wait := make(chan struct{}) | ||
rp.immediatePublish <- wait | ||
<-wait | ||
} | ||
|
||
func (rp *Republisher) Close() error { | ||
err := rp.publish(rp.ctx) | ||
err := rp.PublishNow() | ||
rp.cancel() | ||
return err | ||
} | ||
|
@@ -69,7 +51,7 @@ func (rp *Republisher) Close() error { | |
// the next publish occurs in order to more efficiently batch updates. | ||
func (rp *Republisher) Update(c cid.Cid) { | ||
rp.valueLock.Lock() | ||
rp.valueToPublish = c | ||
rp.valueToPublish = &c | ||
rp.valueLock.Unlock() | ||
|
||
select { | ||
|
@@ -106,8 +88,6 @@ func (rp *Republisher) Run() { | |
longer := time.After(rp.TimeoutLong) | ||
|
||
wait: | ||
var valueHasBeenPublished chan struct{} | ||
|
||
select { | ||
case <-rp.ctx.Done(): | ||
return | ||
|
@@ -121,15 +101,9 @@ func (rp *Republisher) Run() { | |
|
||
case <-quick: | ||
case <-longer: | ||
case valueHasBeenPublished = <-rp.immediatePublish: | ||
} | ||
|
||
err := rp.publish(rp.ctx) | ||
if valueHasBeenPublished != nil { | ||
// The user is waiting in `WaitPub` with this channel, signal | ||
// that the `publish` has happened. | ||
valueHasBeenPublished <- struct{}{} | ||
} | ||
err := rp.PublishNow() | ||
if err != nil { | ||
log.Errorf("republishRoot error: %s", err) | ||
} | ||
|
@@ -139,17 +113,28 @@ func (rp *Republisher) Run() { | |
|
||
// Wrapper function around the user-defined `pubfunc`. It publishes | ||
// the (last) `valueToPublish` set and registers it in `lastValuePublished`. | ||
func (rp *Republisher) publish(ctx context.Context) error { | ||
// TODO: Allow passing a value to `PublishNow` which supersedes the | ||
// internal `valueToPublish`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure if we want to allow this. Users shouldn't swap out the MFS root using the republisher. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure I understand the comment, what do you mean by swap out? The There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Got it. Yeah, that makes sense. (context: I keep thinking we're exposing the republisher to the user) |
||
func (rp *Republisher) PublishNow() error { | ||
|
||
rp.valueLock.Lock() | ||
topub := rp.valueToPublish | ||
extractedValue := rp.valueToPublish | ||
rp.valueLock.Unlock() | ||
|
||
err := rp.pubfunc(ctx, topub) | ||
if extractedValue == nil { | ||
return nil | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A concurrent call won't actually wait. We may need a RwMutex here. |
||
// If this value is `nil` it means we've done a publish | ||
// since the last `Update`. | ||
} | ||
|
||
err := rp.pubfunc(rp.ctx, *extractedValue); | ||
if err != nil { | ||
return err | ||
} | ||
|
||
rp.valueLock.Lock() | ||
rp.lastValuePublished = topub | ||
rp.valueToPublish = nil | ||
rp.valueLock.Unlock() | ||
|
||
return nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this a pointer ? Can the CID be modified (elsewhere) while we are waiting to publish ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah I think I see how this handled in
PublishNow()
with theextractedValue == nil
check.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It shouldn't be, the
Update
API hasn't changed, we still make a local copy.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should just be a
cid.Cid
and should be set tocid.Undef
when "nil". (probably should have beencid.Nil
but I didn't win that argument).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I thought of that at first but we do
cid.Undef
to issue publish orders, at least in some tests,go-mfs/repub_test.go
Lines 43 to 45 in 4fb6dc4
so I think it violates the semantics I would expect of a
nil
value.I agree that we should fix that and provide a
cid.Nil
but in the meanwhile I don't see the harm in implementing thenil
with a pointer for an internal variable.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The pointer is fine but shouldn't be necessary. Really, we should fix that test, passing the "Undef" CID is should be equivalent to a "nil" CID (and passing a nil CID to
rp.Update
doesn't make sense).