{"action":"created","comment":{"url":"https://api.github.com/repos/rivine/rivine/pulls/comments/175035418","pull_request_review_id":104483153,"id":175035418,"diff_hunk":"@@ -0,0 +1,114 @@\n+package datastore\n+\n+import (\n+\t\"bytes\"\n+\t\"sync\"\n+\n+\t\"github.com/rivine/rivine/persist\"\n+\n+\t\"github.com/rivine/rivine/encoding\"\n+\t\"github.com/rivine/rivine/modules\"\n+\t\"github.com/rivine/rivine/types\"\n+)\n+\n+type (\n+\t// NamespaceManager keeps track of data for a namespace\n+\tNamespaceManager struct {\n+\t\t// Namespace is the namepsace we are tracking\n+\t\tNamespace Namespace\n+\t\t// State of the manager\n+\t\tState NamespaceManagerState\n+\t\t// Buffer for the incomming blocks so replication is delayed\n+\t\t// and we can prevent deletion of data\n+\t\tBuffer *BlockBuffer\n+\t\t// Cs we are subscribed to\n+\t\tCs modules.ConsensusSet\n+\t\t// DB used to replicate the data\n+\t\tDB Database\n+\n+\t\tlog *persist.Logger\n+\n+\t\tmu sync.Mutex\n+\t}\n+\n+\t// NamespaceManagerState is the internal state of a namespace manager\n+\tNamespaceManagerState struct {\n+\t\t// BlockHeight is the current block height of the tracker\n+\t\tBlockHeight types.BlockHeight\n+\t\t// RecentChangeID is the last consensuschangeid we received\n+\t\tRecentChangeID modules.ConsensusChangeID\n+\t\t// DataID is the last data id we stored\n+\t\tDataID DataID\n+\t\t// SubscribeStart is an optional timestamp, all data before this is ignored\n+\t\tSubscribeStart types.Timestamp\n+\t}\n+)\n+\n+// NewNamespaceManager initializes a new namespace manager for a given namespace,\n+// with a timestamp to start tracking from\n+func NewNamespaceManager(namespace Namespace, db Database, ts types.Timestamp, log *persist.Logger) *NamespaceManager {\n+\tnsm := &NamespaceManager{\n+\t\tState: NamespaceManagerState{\n+\t\t\tSubscribeStart: ts,\n+\t\t},\n+\t\tNamespace: namespace,\n+\t\tBuffer:    NewBlockBuffer(),\n+\t\tDB:        db,\n+\t\tlog:       log,\n+\t}\n+\treturn nsm\n+}\n+\n+// Save updates the state of the namespace manager in the database\n+func (nsm *NamespaceManager) Save() error {\n+\treturn nsm.DB.SaveManager(nsm)\n+}\n+\n+// Delete removes the namespace manager from the database\n+func (nsm *NamespaceManager) Delete() error {\n+\treturn nsm.DB.DeleteManager(nsm)\n+}\n+\n+// SubscribeCs subscribes this namespace manager to the given consensus set\n+func (nsm *NamespaceManager) SubscribeCs(cs modules.ConsensusSet) {\n+\tnsm.mu.Lock()\n+\tnsm.Cs = cs\n+\tnsm.mu.Unlock()\n+\n+\t// We can't lock here since ConsensusSetSubscribe will push all changes until\n+\t// we are caught up with the current thread, and the update function already locks.\n+\t// Then again, we should only ever call subscribe during the creation of a namespace\n+\t// manager in the datastore, (either loading or a new subscription), so this should be fine.\n+\n+\terr := cs.ConsensusSetSubscribe(nsm, nsm.State.RecentChangeID)\n+\tif err != nil {\n+\t\tnsm.log.Severe(\"Namespace manager failed to subscribe to consensus set: \", err)\n+\t}\n+}\n+\n+// UnSubscribeCs removes this namespace manager from the previously subscribed consensus set\n+func (nsm *NamespaceManager) UnSubscribeCs() {","path":"modules/datastore/namespacemanager.go","position":90,"original_position":90,"commit_id":"3280c6b2b69abf8efadba5fff8641486e7da29db","original_commit_id":"3280c6b2b69abf8efadba5fff8641486e7da29db","user":{"login":"GlenDC","id":3900482,"avatar_url":"https://avatars2.githubusercontent.com/u/3900482?v=4","gravatar_id":"","url":"https://api.github.com/users/GlenDC","html_url":"https://github.com/GlenDC","followers_url":"https://api.github.com/users/GlenDC/followers","following_url":"https://api.github.com/users/GlenDC/following{/other_user}","gists_url":"https://api.github.com/users/GlenDC/gists{/gist_id}","starred_url":"https://api.github.com/users/GlenDC/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/GlenDC/subscriptions","organizations_url":"https://api.github.com/users/GlenDC/orgs","repos_url":"https://api.github.com/users/GlenDC/repos","events_url":"https://api.github.com/users/GlenDC/events{/privacy}","received_events_url":"https://api.github.com/users/GlenDC/received_events","type":"User","site_admin":false},"body":"I don't see the point of this func, should just be part of the close function, try to keep your API surface as small as possible when designing","created_at":"2018-03-16T09:31:00Z","updated_at":"2018-03-16T09:32:19Z","html_url":"https://github.com/rivine/rivine/pull/139#discussion_r175035418","pull_request_url":"https://api.github.com/repos/rivine/rivine/pulls/139","author_association":"COLLABORATOR","_links":{"self":{"href":"https://api.github.com/repos/rivine/rivine/pulls/comments/175035418"},"html":{"href":"https://github.com/rivine/rivine/pull/139#discussion_r175035418"},"pull_request":{"href":"https://api.github.com/repos/rivine/rivine/pulls/139"}}},"pull_request":{"url":"https://api.github.com/repos/rivine/rivine/pulls/139","id":173883181,"html_url":"https://github.com/rivine/rivine/pull/139","diff_url":"https://github.com/rivine/rivine/pull/139.diff","patch_url":"https://github.com/rivine/rivine/pull/139.patch","issue_url":"https://api.github.com/repos/rivine/rivine/issues/139","number":139,"state":"open","locked":false,"title":"Data replication","user":{"login":"LeeSmet","id":22023708,"avatar_url":"https://avatars0.githubusercontent.com/u/22023708?v=4","gravatar_id":"","url":"https://api.github.com/users/LeeSmet","html_url":"https://github.com/LeeSmet","followers_url":"https://api.github.com/users/LeeSmet/followers","following_url":"https://api.github.com/users/LeeSmet/following{/other_user}","gists_url":"https://api.github.com/users/LeeSmet/gists{/gist_id}","starred_url":"https://api.github.com/users/LeeSmet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/LeeSmet/subscriptions","organizations_url":"https://api.github.com/users/LeeSmet/orgs","repos_url":"https://api.github.com/users/LeeSmet/repos","events_url":"https://api.github.com/users/LeeSmet/events{/privacy}","received_events_url":"https://api.github.com/users/LeeSmet/received_events","type":"User","site_admin":false},"body":"WIP\r\n\r\nJust to show the current progress\r\n\r\nRight now there is no filtering. Managing consensus change seems to work fine (as in: I don't get errors), though i only have my old testing network which doesnt have data in the blocks (so its just updating and loading the blocheight, changeid and dataid).\r\n\r\nfor the dataID: for now its a uint32, which starts at 0 and is incremented for every txn in every block. So it will overflow after 4.2 billion txns. If we say 1K txns per block, thats 4.2M blocks, which at a 10 min rate would mean that the overflow happens in roughly 100 years (of the top of my head). I can live with that.\r\n\r\nAny suggestions are welcome.\r\n\r\nP.S.: I am aware that there is no interface exposed yet in the modules package for the datastore. Due to the limited number of methods available, I'm unsure if its a good idea to implement that (currently only has a close method)\r\n\r\nP.P.S.: Don't mind the build.critical error handling. It'l change, and its some nice debug output","created_at":"2018-03-08T23:46:21Z","updated_at":"2018-03-16T09:32:19Z","closed_at":null,"merged_at":null,"merge_commit_sha":"fbff1e362c2b30d522adf127a996246da62a1c4e","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":504150700,"url":"https://api.github.com/repos/rivine/rivine/labels/state_inprogress","name":"state_inprogress","color":"c2e0c6","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/rivine/rivine/pulls/139/commits","review_comments_url":"https://api.github.com/repos/rivine/rivine/pulls/139/comments","review_comment_url":"https://api.github.com/repos/rivine/rivine/pulls/comments{/number}","comments_url":"https://api.github.com/repos/rivine/rivine/issues/139/comments","statuses_url":"https://api.github.com/repos/rivine/rivine/statuses/3280c6b2b69abf8efadba5fff8641486e7da29db","head":{"label":"rivine:data_replication","ref":"data_replication","sha":"3280c6b2b69abf8efadba5fff8641486e7da29db","user":{"login":"rivine","id":11573943,"avatar_url":"https://avatars0.githubusercontent.com/u/11573943?v=4","gravatar_id":"","url":"https://api.github.com/users/rivine","html_url":"https://github.com/rivine","followers_url":"https://api.github.com/users/rivine/followers","following_url":"https://api.github.com/users/rivine/following{/other_user}","gists_url":"https://api.github.com/users/rivine/gists{/gist_id}","starred_url":"https://api.github.com/users/rivine/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rivine/subscriptions","organizations_url":"https://api.github.com/users/rivine/orgs","repos_url":"https://api.github.com/users/rivine/repos","events_url":"https://api.github.com/users/rivine/events{/privacy}","received_events_url":"https://api.github.com/users/rivine/received_events","type":"Organization","site_admin":false},"repo":{"id":68117617,"name":"rivine","full_name":"rivine/rivine","owner":{"login":"rivine","id":11573943,"avatar_url":"https://avatars0.githubusercontent.com/u/11573943?v=4","gravatar_id":"","url":"https://api.github.com/users/rivine","html_url":"https://github.com/rivine","followers_url":"https://api.github.com/users/rivine/followers","following_url":"https://api.github.com/users/rivine/following{/other_user}","gists_url":"https://api.github.com/users/rivine/gists{/gist_id}","starred_url":"https://api.github.com/users/rivine/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rivine/subscriptions","organizations_url":"https://api.github.com/users/rivine/orgs","repos_url":"https://api.github.com/users/rivine/repos","events_url":"https://api.github.com/users/rivine/events{/privacy}","received_events_url":"https://api.github.com/users/rivine/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/rivine/rivine","description":"Blockchain technology for creating custom chains.","fork":false,"url":"https://api.github.com/repos/rivine/rivine","forks_url":"https://api.github.com/repos/rivine/rivine/forks","keys_url":"https://api.github.com/repos/rivine/rivine/keys{/key_id}","collaborators_url":"https://api.github.com/repos/rivine/rivine/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/rivine/rivine/teams","hooks_url":"https://api.github.com/repos/rivine/rivine/hooks","issue_events_url":"https://api.github.com/repos/rivine/rivine/issues/events{/number}","events_url":"https://api.github.com/repos/rivine/rivine/events","assignees_url":"https://api.github.com/repos/rivine/rivine/assignees{/user}","branches_url":"https://api.github.com/repos/rivine/rivine/branches{/branch}","tags_url":"https://api.github.com/repos/rivine/rivine/tags","blobs_url":"https://api.github.com/repos/rivine/rivine/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/rivine/rivine/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/rivine/rivine/git/refs{/sha}","trees_url":"https://api.github.com/repos/rivine/rivine/git/trees{/sha}","statuses_url":"https://api.github.com/repos/rivine/rivine/statuses/{sha}","languages_url":"https://api.github.com/repos/rivine/rivine/languages","stargazers_url":"https://api.github.com/repos/rivine/rivine/stargazers","contributors_url":"https://api.github.com/repos/rivine/rivine/contributors","subscribers_url":"https://api.github.com/repos/rivine/rivine/subscribers","subscription_url":"https://api.github.com/repos/rivine/rivine/subscription","commits_url":"https://api.github.com/repos/rivine/rivine/commits{/sha}","git_commits_url":"https://api.github.com/repos/rivine/rivine/git/commits{/sha}","comments_url":"https://api.github.com/repos/rivine/rivine/comments{/number}","issue_comment_url":"https://api.github.com/repos/rivine/rivine/issues/comments{/number}","contents_url":"https://api.github.com/repos/rivine/rivine/contents/{+path}","compare_url":"https://api.github.com/repos/rivine/rivine/compare/{base}...{head}","merges_url":"https://api.github.com/repos/rivine/rivine/merges","archive_url":"https://api.github.com/repos/rivine/rivine/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/rivine/rivine/downloads","issues_url":"https://api.github.com/repos/rivine/rivine/issues{/number}","pulls_url":"https://api.github.com/repos/rivine/rivine/pulls{/number}","milestones_url":"https://api.github.com/repos/rivine/rivine/milestones{/number}","notifications_url":"https://api.github.com/repos/rivine/rivine/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/rivine/rivine/labels{/name}","releases_url":"https://api.github.com/repos/rivine/rivine/releases{/id}","deployments_url":"https://api.github.com/repos/rivine/rivine/deployments","created_at":"2016-09-13T14:45:18Z","updated_at":"2018-03-15T18:31:26Z","pushed_at":"2018-03-16T09:31:39Z","git_url":"git://github.com/rivine/rivine.git","ssh_url":"git@github.com:rivine/rivine.git","clone_url":"https://github.com/rivine/rivine.git","svn_url":"https://github.com/rivine/rivine","homepage":"","size":17703,"stargazers_count":8,"watchers_count":8,"language":"Go","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":6,"mirror_url":null,"archived":false,"open_issues_count":55,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit"},"forks":6,"open_issues":55,"watchers":8,"default_branch":"master"}},"base":{"label":"rivine:master","ref":"master","sha":"0e4a2e95e9d10e63663f8c22d49f7bf92cc100e8","user":{"login":"rivine","id":11573943,"avatar_url":"https://avatars0.githubusercontent.com/u/11573943?v=4","gravatar_id":"","url":"https://api.github.com/users/rivine","html_url":"https://github.com/rivine","followers_url":"https://api.github.com/users/rivine/followers","following_url":"https://api.github.com/users/rivine/following{/other_user}","gists_url":"https://api.github.com/users/rivine/gists{/gist_id}","starred_url":"https://api.github.com/users/rivine/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rivine/subscriptions","organizations_url":"https://api.github.com/users/rivine/orgs","repos_url":"https://api.github.com/users/rivine/repos","events_url":"https://api.github.com/users/rivine/events{/privacy}","received_events_url":"https://api.github.com/users/rivine/received_events","type":"Organization","site_admin":false},"repo":{"id":68117617,"name":"rivine","full_name":"rivine/rivine","owner":{"login":"rivine","id":11573943,"avatar_url":"https://avatars0.githubusercontent.com/u/11573943?v=4","gravatar_id":"","url":"https://api.github.com/users/rivine","html_url":"https://github.com/rivine","followers_url":"https://api.github.com/users/rivine/followers","following_url":"https://api.github.com/users/rivine/following{/other_user}","gists_url":"https://api.github.com/users/rivine/gists{/gist_id}","starred_url":"https://api.github.com/users/rivine/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rivine/subscriptions","organizations_url":"https://api.github.com/users/rivine/orgs","repos_url":"https://api.github.com/users/rivine/repos","events_url":"https://api.github.com/users/rivine/events{/privacy}","received_events_url":"https://api.github.com/users/rivine/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/rivine/rivine","description":"Blockchain technology for creating custom chains.","fork":false,"url":"https://api.github.com/repos/rivine/rivine","forks_url":"https://api.github.com/repos/rivine/rivine/forks","keys_url":"https://api.github.com/repos/rivine/rivine/keys{/key_id}","collaborators_url":"https://api.github.com/repos/rivine/rivine/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/rivine/rivine/teams","hooks_url":"https://api.github.com/repos/rivine/rivine/hooks","issue_events_url":"https://api.github.com/repos/rivine/rivine/issues/events{/number}","events_url":"https://api.github.com/repos/rivine/rivine/events","assignees_url":"https://api.github.com/repos/rivine/rivine/assignees{/user}","branches_url":"https://api.github.com/repos/rivine/rivine/branches{/branch}","tags_url":"https://api.github.com/repos/rivine/rivine/tags","blobs_url":"https://api.github.com/repos/rivine/rivine/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/rivine/rivine/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/rivine/rivine/git/refs{/sha}","trees_url":"https://api.github.com/repos/rivine/rivine/git/trees{/sha}","statuses_url":"https://api.github.com/repos/rivine/rivine/statuses/{sha}","languages_url":"https://api.github.com/repos/rivine/rivine/languages","stargazers_url":"https://api.github.com/repos/rivine/rivine/stargazers","contributors_url":"https://api.github.com/repos/rivine/rivine/contributors","subscribers_url":"https://api.github.com/repos/rivine/rivine/subscribers","subscription_url":"https://api.github.com/repos/rivine/rivine/subscription","commits_url":"https://api.github.com/repos/rivine/rivine/commits{/sha}","git_commits_url":"https://api.github.com/repos/rivine/rivine/git/commits{/sha}","comments_url":"https://api.github.com/repos/rivine/rivine/comments{/number}","issue_comment_url":"https://api.github.com/repos/rivine/rivine/issues/comments{/number}","contents_url":"https://api.github.com/repos/rivine/rivine/contents/{+path}","compare_url":"https://api.github.com/repos/rivine/rivine/compare/{base}...{head}","merges_url":"https://api.github.com/repos/rivine/rivine/merges","archive_url":"https://api.github.com/repos/rivine/rivine/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/rivine/rivine/downloads","issues_url":"https://api.github.com/repos/rivine/rivine/issues{/number}","pulls_url":"https://api.github.com/repos/rivine/rivine/pulls{/number}","milestones_url":"https://api.github.com/repos/rivine/rivine/milestones{/number}","notifications_url":"https://api.github.com/repos/rivine/rivine/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/rivine/rivine/labels{/name}","releases_url":"https://api.github.com/repos/rivine/rivine/releases{/id}","deployments_url":"https://api.github.com/repos/rivine/rivine/deployments","created_at":"2016-09-13T14:45:18Z","updated_at":"2018-03-15T18:31:26Z","pushed_at":"2018-03-16T09:31:39Z","git_url":"git://github.com/rivine/rivine.git","ssh_url":"git@github.com:rivine/rivine.git","clone_url":"https://github.com/rivine/rivine.git","svn_url":"https://github.com/rivine/rivine","homepage":"","size":17703,"stargazers_count":8,"watchers_count":8,"language":"Go","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":6,"mirror_url":null,"archived":false,"open_issues_count":55,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit"},"forks":6,"open_issues":55,"watchers":8,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/rivine/rivine/pulls/139"},"html":{"href":"https://github.com/rivine/rivine/pull/139"},"issue":{"href":"https://api.github.com/repos/rivine/rivine/issues/139"},"comments":{"href":"https://api.github.com/repos/rivine/rivine/issues/139/comments"},"review_comments":{"href":"https://api.github.com/repos/rivine/rivine/pulls/139/comments"},"review_comment":{"href":"https://api.github.com/repos/rivine/rivine/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/rivine/rivine/pulls/139/commits"},"statuses":{"href":"https://api.github.com/repos/rivine/rivine/statuses/3280c6b2b69abf8efadba5fff8641486e7da29db"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"GlenDC"}}