state/nodestore: in memory representation of nodes
Initial work on a nodestore which stores all of the nodes and their relations in memory with relationship for peers precalculated. It is a copy-on-write structure, replacing the "snapshot" when a change to the structure occurs. It is optimised for reads, and while batches are not fast, they are grouped together to do less of the expensive peer calculation if there are many changes rapidly. Writes will block until commited, while reads are never blocked. Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
This commit is contained in:
parent
38be30b6d4
commit
9d236571f4
35 changed files with 3960 additions and 1317 deletions
|
|
@ -547,6 +547,8 @@ func TestUpdateHostnameFromClient(t *testing.T) {
|
|||
err = scenario.WaitForTailscaleSync()
|
||||
assertNoErrSync(t, err)
|
||||
|
||||
// Wait for nodestore batch processing to complete
|
||||
// NodeStore batching timeout is 500ms, so we wait up to 1 second
|
||||
var nodes []*v1.Node
|
||||
assert.EventuallyWithT(t, func(ct *assert.CollectT) {
|
||||
err := executeAndUnmarshal(
|
||||
|
|
@ -642,27 +644,34 @@ func TestUpdateHostnameFromClient(t *testing.T) {
|
|||
err = scenario.WaitForTailscaleSync()
|
||||
assertNoErrSync(t, err)
|
||||
|
||||
err = executeAndUnmarshal(
|
||||
headscale,
|
||||
[]string{
|
||||
"headscale",
|
||||
"node",
|
||||
"list",
|
||||
"--output",
|
||||
"json",
|
||||
},
|
||||
&nodes,
|
||||
)
|
||||
// Wait for nodestore batch processing to complete
|
||||
// NodeStore batching timeout is 500ms, so we wait up to 1 second
|
||||
assert.Eventually(t, func() bool {
|
||||
err = executeAndUnmarshal(
|
||||
headscale,
|
||||
[]string{
|
||||
"headscale",
|
||||
"node",
|
||||
"list",
|
||||
"--output",
|
||||
"json",
|
||||
},
|
||||
&nodes,
|
||||
)
|
||||
|
||||
assertNoErr(t, err)
|
||||
assert.Len(t, nodes, 3)
|
||||
if err != nil || len(nodes) != 3 {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, node := range nodes {
|
||||
hostname := hostnames[strconv.FormatUint(node.GetId(), 10)]
|
||||
givenName := fmt.Sprintf("%d-givenname", node.GetId())
|
||||
assert.Equal(t, hostname+"NEW", node.GetName())
|
||||
assert.Equal(t, givenName, node.GetGivenName())
|
||||
}
|
||||
for _, node := range nodes {
|
||||
hostname := hostnames[strconv.FormatUint(node.GetId(), 10)]
|
||||
givenName := fmt.Sprintf("%d-givenname", node.GetId())
|
||||
if node.GetName() != hostname+"NEW" || node.GetGivenName() != givenName {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}, time.Second, 50*time.Millisecond, "hostname updates should be reflected in node list with NEW suffix")
|
||||
}
|
||||
|
||||
func TestExpireNode(t *testing.T) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue