-
Notifications
You must be signed in to change notification settings - Fork 53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Add P2P collection topic subscription #1086
Conversation
Codecov Report
@@ Coverage Diff @@
## develop #1086 +/- ##
===========================================
- Coverage 68.27% 67.50% -0.77%
===========================================
Files 173 178 +5
Lines 16338 16616 +278
===========================================
+ Hits 11154 11216 +62
- Misses 4253 4455 +202
- Partials 931 945 +14
|
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.
Mostly looks good to me :) And I like what you did to the tests. I do think there is a destructive race condition though that could corrupt the persisted p2pcollection data and I would like the public interface documentation to be expanded.
require.NoError(t, err) | ||
} | ||
|
||
docInNodes := mapNodesToDoc(test) |
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.
praise: Took me a while to think it over, and whilst I generally dislike merging of two different concepts in the same block (here the create/update, and the wait mechanics), I think the new code is easier to understand and harder to break (particularly important with wg stuff where breaking might deadlock) - thanks for this change :)
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.
Thanks Andy :)
client/db.go
Outdated
@@ -51,6 +51,13 @@ type DB interface { | |||
// GetAllReplicators returns the full list of replicators with their | |||
// subscribed schemas. | |||
GetAllReplicators(ctx context.Context) ([]Replicator, error) | |||
|
|||
// AddP2PCollection adds a P2P collection to the stored list |
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.
todo: I do not know what the stored list
means here, I can guess, but as this is a public interface I think this needs to be explained further. (same for the other new funcs in here).
todo: I think this comment should also highlight that the item to be stored must be a collection id, and that it will error if it is not an id of an existing collection. (same for RemoveP2PCollection)
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.
done ✅
Let me know if you like the change.
client/db.go
Outdated
// RemoveP2PCollection removes P2P collection from the stored list | ||
RemoveP2PCollection(ctx context.Context, collectionID string) error | ||
// GetAllP2PCollections returns the full list of P2P collections | ||
GetAllP2PCollections(ctx context.Context) ([]string, error) |
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.
thought: DB
is growing quite a bit, and the P2P funcs are starting to outnumber core database funcs - it might be nice to break them out to a different (child?) object, or perhaps just split the interface into two (one core, one P2P, both implemented by db.db). Really doesn't have to be done now if we want to do this, just something to bear in mind).
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.
I created an embedded P2P interface. Let me know if you like that change.
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.
Nice - thanks :) I like it.
Further thought for future (not now) - I dont think the DB interface should inherit the P2P one, instead there should be 3:
P2P {...}
DB {...}
Defra{ //Naming is horrible, and giving this and DB meaningful names may be tricky
DB
P2P
}
This would allow consumers to properly segregate their use cases if they want (also really useful for mocking, if so inclined). That way only their P2P code has access to the P2P interface, and core code the core DB stuff. Probs less important in Go as interfaces are not explicitly linked, but still nice I think (plus DB inheriting from P2P is a bit odd longer-term).
client/db.go
Outdated
AddP2PCollection(ctx context.Context, collectionID string) error | ||
// RemoveP2PCollection removes P2P collection from the stored list | ||
RemoveP2PCollection(ctx context.Context, collectionID string) error | ||
// GetAllP2PCollections returns the full list of P2P collections |
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.
todo: I do not think this comment explains the return value well enough - it is just a string array and nothing in the signature or current comment states which values it contains P2P collections
are presumably not just arbitrary strings, and it could easily be read as meaning []client.Collection
.
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.
done ✅
Let me know what you think.
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.
looks good - thanks :)
db/p2p_collections.go
Outdated
) | ||
|
||
// AddP2PCollection adds a P2P collection to the stored list | ||
func (db *db) AddP2PCollection(ctx context.Context, collectionID string) error { |
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.
todo: It looks like there is a race condition in these functions - you dont appear to be protecting against concurrent mutations that are committed between fetching the existing collections, and saving the user defined values - it also looks like this would be potentially destructive, with invalid values being persisted into the database (e.g. the added collection is deleted between the 2 lines, or another actor concurrently updates the persisted value with conflicting changes).
I think a shared mutex (lol...) would solve the worst of this fairly easily (but won't fully protect against conflicting changes, I think that would have to be done in user-space without a more fancy means of persisting these values).
It would also be good to have tests for this, but it might be too painful to do so at this point.
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.
done ✅
I've changed it to a per collection ID key. No more overstepping. Let me know what you think.
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.
Much much nicer than a mutex lol - thanks 😁 Should make Schema Update stuff much easier too.
db/p2p_collections.go
Outdated
} | ||
|
||
// RemoveP2PCollection removes P2P collection from the stored list | ||
func (db *db) RemoveP2PCollection(ctx context.Context, collectionID string) error { |
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.
comment: I think it is easy to miss this with Schema Updates, this should be updated if/when collections are deleted. I'll note this on the Schema Update ticket. I cant spot an obvious way to make this linkage/requirement stronger/more obvious though.
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.
Good idea to keep track of it.
Changed the storing mechanics from a single key with an array to each collectionID having it’s own key.
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.
Looks good, and I really like the recent changes (they are better than the suggestions/thoughts I posted) :)
Relevant issue(s) Resolves #1081 Description This PR adds the option to subscribe to events on a given collection by using the collectionID (in reality schemaID for now as there is no globalSchemaID or anything similar) as the pubsub topic. It adds commands to the CLI to add, remove and list the P2P collection topics.
Relevant issue(s) Resolves sourcenetwork#1081 Description This PR adds the option to subscribe to events on a given collection by using the collectionID (in reality schemaID for now as there is no globalSchemaID or anything similar) as the pubsub topic. It adds commands to the CLI to add, remove and list the P2P collection topics.
Relevant issue(s)
Resolves #1081
Description
This PR adds the option to subscribe to events on a given collection by using the collectionID (in reality schemaID for now as there is no globalSchemaID or anything similar) as the pubsub topic. It adds commands to the CLI to add, remove and list the P2P collection topics.
Tasks
How has this been tested?
unit tests and integration tests
Specify the platform(s) on which this was tested: