Skip to content
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

Merged
merged 13 commits into from
Feb 11, 2023

Conversation

fredcarle
Copy link
Collaborator

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

  • I made sure the code is well commented, particularly hard-to-understand areas.
  • I made sure the repository-held documentation is changed accordingly.
  • I made sure the pull request title adheres to the conventional commit style (the subset used in the project can be found in tools/configs/chglog/config.yml).
  • I made sure to discuss its limitations such as threats to validity, vulnerability to mistake and misuse, robustness to invalidation of assumptions, resource requirements, ...

How has this been tested?

unit tests and integration tests

Specify the platform(s) on which this was tested:

  • MacOS

@fredcarle fredcarle added feature New feature or request area/collections Related to the collections system area/p2p Related to the p2p networking system action/no-benchmark Skips the action that runs the benchmark. area/cli Related to the CLI binary labels Feb 8, 2023
@fredcarle fredcarle added this to the DefraDB v0.5 milestone Feb 8, 2023
@fredcarle fredcarle requested a review from a team February 8, 2023 09:13
@fredcarle fredcarle self-assigned this Feb 8, 2023
@codecov
Copy link

codecov bot commented Feb 8, 2023

Codecov Report

Merging #1086 (e2efce2) into develop (5591416) will decrease coverage by 0.77%.
The diff coverage is 27.56%.

Impacted file tree graph

@@             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     
Impacted Files Coverage Δ
db/errors.go 0.00% <0.00%> (ø)
net/api/client/client.go 0.00% <0.00%> (ø)
net/api/service.go 2.77% <0.00%> (-1.39%) ⬇️
cli/p2p_collection_getall.go 6.06% <6.06%> (ø)
cli/p2p_collection_add.go 7.69% <7.69%> (ø)
cli/p2p_collection_remove.go 7.69% <7.69%> (ø)
net/peer.go 47.65% <23.52%> (-3.76%) ⬇️
db/p2p_collection.go 60.00% <60.00%> (ø)
net/server.go 59.93% <62.50%> (+0.64%) ⬆️
core/key.go 86.52% <73.68%> (-0.93%) ⬇️
... and 5 more

Copy link
Contributor

@AndrewSisley AndrewSisley left a 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)
Copy link
Contributor

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 :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Andy :)

tests/integration/net/state/utils.go Show resolved Hide resolved
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
Copy link
Contributor

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)

Copy link
Collaborator Author

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)
Copy link
Contributor

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).

Copy link
Collaborator Author

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.

Copy link
Contributor

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
Copy link
Contributor

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.

Copy link
Collaborator Author

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.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good - thanks :)

)

// AddP2PCollection adds a P2P collection to the stored list
func (db *db) AddP2PCollection(ctx context.Context, collectionID string) error {
Copy link
Contributor

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.

Copy link
Collaborator Author

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.

Copy link
Contributor

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.

}

// RemoveP2PCollection removes P2P collection from the stored list
func (db *db) RemoveP2PCollection(ctx context.Context, collectionID string) error {
Copy link
Contributor

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.

Copy link
Collaborator Author

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.
Copy link
Contributor

@AndrewSisley AndrewSisley left a 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) :)

@fredcarle fredcarle merged commit 5881187 into develop Feb 11, 2023
@fredcarle fredcarle deleted the fredcarle/feat/I1081-p2p-collection-evt branch February 11, 2023 06:26
shahzadlone pushed a commit that referenced this pull request Apr 13, 2023
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.
shahzadlone pushed a commit to shahzadlone/defradb that referenced this pull request Feb 23, 2024
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
action/no-benchmark Skips the action that runs the benchmark. area/cli Related to the CLI binary area/collections Related to the collections system area/p2p Related to the p2p networking system feature New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

P2P Subscribe to collection events
2 participants