Comments (5)
But, the client shouldn't be expected to book keep who the leader is, should it? Maybe I am misunderstanding some basic concepts.
Yes, currently this is the client's responsibility. go-dqlite has logic to forward requests to the current leader, and so does the WIP high-level C client library. It's definitely a bit inconvenient if you're writing your own client.
Note that any client of a distributed system must have knowledge of at least some of the nodes that are part of the system. That is necessary because any of those nodes might be down and in that case the client will need to try with another node. That logic might look like:
for (i = 0; i < n; i++) {
node = all_nodes_the_client_knows_about[i];
rv = try_connect(node);
if (rv == 0) {
break;
}
}
Since that type of logic must be in place in the client no matter what, it should only be necessary to modify it slightly, like this:
for (i = 0; i < n; i++) {
node = all_nodes_the_client_knows_about[i];
rv = try_connect(node);
if (rv == 0 && node->is_leader) {
break;
}
}
All that being said, implementing request forwarding so that the client can connect to any node is surely possible. Note though that it will increase latency (there will be an extra network hop, like a proxy), so all in all perhaps it's better to have the client do a bit of extra work.
from dqlite.
But, the client shouldn't be expected to book keep who the leader is, should it? Maybe I am misunderstanding some basic concepts.
Yes, currently this is the client's responsibility. go-dqlite has logic to forward requests to the current leader, and so does the WIP high-level C client library. It's definitely a bit inconvenient if you're writing your own client.
Note that any client of a distributed system must have knowledge of at least some of the nodes that are part of the system. That is necessary because any of those nodes might be down and in that case the client will need to try with another node. That logic might look like:
for (i = 0; i < n; i++) { node = all_nodes_the_client_knows_about[i]; rv = try_connect(node); if (rv == 0) { break; } }Since that type of logic must be in place in the client no matter what, it should only be necessary to modify it slightly, like this:
for (i = 0; i < n; i++) { node = all_nodes_the_client_knows_about[i]; rv = try_connect(node); if (rv == 0 && node->is_leader) { break; } }All that being said, implementing request forwarding so that the client can connect to any node is surely possible. Note though that it will increase latency (there will be an extra network hop, like a proxy), so all in all perhaps it's better to have the client do a bit of extra work.
So I tried doing something similar to this, but what I am seeing is that (going back to my diagram above) instance B's copy of the database does not match instance A's once instance A has closed and handed leadership to instance B.
To give some more detail:
Instance A initializes it's dqlite_server with:
const char *server_address = "127.0.0.1:8080";
int err;
err = dqlite_server_create(aDir, aServer);
err = dqlite_server_set_address(*aServer, server_address);
err = dqlite_server_set_auto_bootstrap(*aServer, true);
err = dqlite_server_start(*aServer);
and Instance B initializes its dqlite_server with:
const char *addrs[] = {"127.0.0.1:8080"};
const char *server_address = "127.0.0.1:8082";
int err;
int thisClientID = 1234;
err = dqlite_server_create(aDir, aServer);
err = dqlite_server_set_address(*aServer, server_address);
err = dqlite_server_set_auto_join(*aServer, addrs, 1);
err =
dqlite_server_set_connect_func(*aServer, endpointConnect, &thisClientID);
err = dqlite_server_start(*aServer);
I excluded endpointConnect()
but it definitely connects to instance A.
- After everything is initialized, instance A successfully creates a database, adds some content via an INSERT, and reads it back confirming it's there via a SELECT.
- At this point, instance A pauses at which point instance B is started and attempts to connect to instance A's dqlite_server, which it does successfully.
- Instance B then successfully reads one of the tables from instance A's dqlite_server via a SELECT command.
- At this point, I manually continue instance A, and it gracefully closes, and calls
dqlite_server_handover()
before instance A exits. - I then continue instance B, and it attempts to make another SELECT call, this time failing (because its connection to instance A's dqlite_server no longer exists). It then successfully connects to its own instance of dqlite_server.
- It then is required to send the single world containing the protocol version, the open database message (containing the same database name that instance A created), and finally the SELECT call, which it does successfully.
- Instance B's dqlite_server then responds with a Failure Response message containing "no such table: <table name that was created by instance A>".
From this, it appears that information applied to the dqlite_server leader is not being propagated to other dqlite_servers.
What am I doing incorrectly?
Edit: Got it working. Found a test case that outlines how this should be done, and followed that.
from dqlite.
But, the client shouldn't be expected to book keep who the leader is, should it? Maybe I am misunderstanding some basic concepts.
Yes, currently this is the client's responsibility. go-dqlite has logic to forward requests to the current leader, and so does the WIP high-level C client library. It's definitely a bit inconvenient if you're writing your own client.
from dqlite.
But, the client shouldn't be expected to book keep who the leader is, should it? Maybe I am misunderstanding some basic concepts.
Yes, currently this is the client's responsibility. go-dqlite has logic to forward requests to the current leader, and so does the WIP high-level C client library. It's definitely a bit inconvenient if you're writing your own client.
Speaking of that work in progress C client library. Any update as to when that will be completed?
from dqlite.
Speaking of that work in progress C client library. Any update as to when that will be completed?
I apologize for the delay -- I put #525 aside in favor of other work that we saw as higher-priority. I intend to return to it soon.
from dqlite.
Related Issues (20)
- Nested barriers
- 1.16.0: test suite fails HOT 17
- Method to be informed about latest change in table HOT 2
- Several singular nodes joined later together HOT 2
- Run dqlite tests against most recent SQLite release. HOT 1
- Clarification on dqlite read operations HOT 1
- 1.16.2: build fails with raft 0.22.0 HOT 3
- Fix Coverity
- Use execinfo.h instead of libbacktrace HOT 3
- Set up tmate action
- Set up a canary PPA to get feedback from LP builders before merge HOT 2
- no known leader error forever
- Node.js bindings HOT 1
- Fix cases where the server can return a FAILURE message with result code 0
- Investigate what causes LXD's dqlite to create lots of singleton closed segments
- Flaky test: cluster/restart HOT 5
- 1.16.4: build fails on linking with missing `raft_register_state_cb` symbol HOT 1
- posix_fallocate extremely slow on ext3 file system HOT 1
- 1.16.5: build fails with `-Wimplicit-function-declaration` HOT 9
- Documentation links are broken HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from dqlite.