dallison / subspace Goto Github PK
View Code? Open in Web Editor NEWSubspace IPC
License: Apache License 2.0
Subspace IPC
License: Apache License 2.0
I've been building a little abstraction layer on top of subspace, and I'm getting some weird behavior in a unit test.
This seems like a flaky issue, 5-10 in 1000 test runs.
I can't really share the code right now, but below is the output of a test that just publishes 9 messages (Star Wars movie ratings, as an example protobuf message) and checks that the subscriber gets all 9 messages. About 5-10 times out of 1000 test runs, the result is that there are 9 publishing calls, but the ordinal number jumps by 2 between each publish, and the subscriber received 18 messages, basically every message is exactly duplicated, as if published twice in a row.
The test setup creates a Server with local=true and a unique socket name (mktemp) which runs on a separate thread at the SetUpTestSuite, and I do have a loop to block until the socket is open (client can Init). Then, one client for the subscriber, one client for the publisher. I publish the nine messages in a simple for-loop, and then I ReadMessage on the subscriber until all messages have been read. All that in a single thread, nothing too special. I tried creating the sub before pub and vice versa, it makes no difference. I tried using one client, makes no difference.
I have no idea where this could be coming from. I can't see how a single call to PublishMessage results in the ordinal getting incremented twice and two messages published (and neither is corrupted, so there must be a copy happening too!). I'm happy to debug it, but I need some idea of where the issue could be coming from.
[ RUN ] TestSubspaceMsgMap.Basic
Publishing new message with of length 37 with payload 000
����ڂٞ
A New Hopeffffff�?
Published message with ordinal 1 size 37
Publishing new message with of length 50 with payload 000
��������
The Empire Strikes Back000000�?
Published message with ordinal 3 size 50
Publishing new message with of length 49 with payload 000
��̗ճ��
The Return of the Jedi�������?
Published message with ordinal 5 size 49
Publishing new message with of length 45 with payload 000
�������
The Phantom Menace000000�?
Published message with ordinal 7 size 45
Publishing new message with of length 47 with payload 000
������ۖ
Attack of the Clones333333�?
Published message with ordinal 9 size 47
Publishing new message with of length 46 with payload 000
���͏��
Revenge of the Sith000000�?
Published message with ordinal 11 size 46
Publishing new message with of length 44 with payload 000
������ʐ
The Force Awakens�������?
Published message with ordinal 13 size 44
Publishing new message with of length 40 with payload 000
����Ǒ��
The Last Jed�������?
Published message with ordinal 16 size 40
Publishing new message with of length 48 with payload 000
���ޚ���
The Rise of Skywalker 333333�?
Published message with ordinal 17 size 48
Source was triggered!
Staging new message with ordinal 1 and payload 000
����ڂٞ
A New Hopeffffff�?
Emitting message 1
Reading next message!
Staging new message with ordinal 2 and payload 000
����ڂٞ
A New Hopeffffff�?
Emitting message 2
Reading next message!
Staging new message with ordinal 3 and payload 000
��������
The Empire Strikes Back000000�?
Emitting message 3
Reading next message!
Staging new message with ordinal 4 and payload 000
��������
The Empire Strikes Back000000�?
Emitting message 4
Reading next message!
Staging new message with ordinal 5 and payload 000
��̗ճ��
The Return of the Jedi�������?
Emitting message 5
Reading next message!
Staging new message with ordinal 6 and payload 000
��̗ճ��
The Return of the Jedi�������?
Emitting message 6
Reading next message!
Staging new message with ordinal 7 and payload 000
�������
The Phantom Menace000000�?
Emitting message 7
Reading next message!
Staging new message with ordinal 8 and payload 000
�������
The Phantom Menace000000�?
Emitting message 8
Reading next message!
Staging new message with ordinal 9 and payload 000
������ۖ
Attack of the Clones333333�?
Emitting message 9
Reading next message!
Staging new message with ordinal 10 and payload 000
������ۖ
Attack of the Clones333333�?
Emitting message 10
Reading next message!
Staging new message with ordinal 11 and payload 000
���͏��
Revenge of the Sith000000�?
Emitting message 11
Reading next message!
Staging new message with ordinal 12 and payload 000
���͏��
Revenge of the Sith000000�?
Emitting message 12
Reading next message!
Staging new message with ordinal 13 and payload 000
������ʐ
The Force Awakens�������?
Emitting message 13
Reading next message!
Staging new message with ordinal 14 and payload 000
������ʐ
The Force Awakens�������?
Emitting message 14
Reading next message!
Staging new message with ordinal 15 and payload 000
����Ǒ��
The Last Jed�������?
Emitting message 15
Reading next message!
Staging new message with ordinal 16 and payload 000
����Ǒ��
The Last Jed�������?
Emitting message 16
Reading next message!
Staging new message with ordinal 17 and payload 000
���ޚ���
The Rise of Skywalker 333333�?
Emitting message 17
Reading next message!
Staging new message with ordinal 18 and payload 000
���ޚ���
The Rise of Skywalker 333333�?
Emitting message 18
Reading next message!
msg_map/subspace_source_test.cc:118: Failure
Value of: reviews_received
Expected: has 9 elements where
element #0 is equal to (8-byte object <00-40 37-F7 52-D4 00-00>, "A New Hope", 4, 0.95),
element #1 is equal to (8-byte object <00-C0 EC-41 22-2A 01-00>, "The Empire Strikes Back", 5, 1),
element #2 is equal to (8-byte object <00-E0 85-5D 7E-80 01-00>, "The Return of the Jedi", 6, 0.9),
element #3 is equal to (8-byte object <00-20 15-E3 3E-4B 03-00>, "The Phantom Menace", 1, 0.5),
element #4 is equal to (8-byte object <00-00 A2-4B 22-A1 03-00>, "Attack of the Clones", 2, 0.6),
element #5 is equal to (8-byte object <00-A0 DD-EF 2D-F7 03-00>, "Revenge of the Sith", 3, 0.75),
element #6 is equal to (8-byte object <00-24 77-C6 35-27 05-00>, "The Force Awakens", 7, 0.8),
element #7 is equal to (8-byte object <00-24 F0-A2 6A-60 05-00>, "The Last Jedi", 8, 0.1),
element #8 is equal to (8-byte object <00-C4 4C-50 2C-9A 05-00>, "The Rise of Skywalker", 9, 0.3)
Actual: { (8-byte object <00-40 37-F7 52-D4 00-00>, "A New Hope", 4, 0.95), (8-byte object <00-40 37-F7 52-D4 00-00>, "A New Hope", 4, 0.95), (8-byte object <00-C0 EC-41 22-2A 01-00>, "The Empire Strikes Back", 5, 1), (8-byte object <00-C0 EC-41 22-2A 01-00>, "The Empire Strikes Back", 5, 1), (8-byte object <00-E0 85-5D 7E-80 01-00>, "The Return of the Jedi", 6, 0.9), (8-byte object <00-E0 85-5D 7E-80 01-00>, "The Return of the Jedi", 6, 0.9), (8-byte object <00-20 15-E3 3E-4B 03-00>, "The Phantom Menace", 1, 0.5), (8-byte object <00-20 15-E3 3E-4B 03-00>, "The Phantom Menace", 1, 0.5), (8-byte object <00-00 A2-4B 22-A1 03-00>, "Attack of the Clones", 2, 0.6), (8-byte object <00-00 A2-4B 22-A1 03-00>, "Attack of the Clones", 2, 0.6), (8-byte object <00-A0 DD-EF 2D-F7 03-00>, "Revenge of the Sith", 3, 0.75), (8-byte object <00-A0 DD-EF 2D-F7 03-00>, "Revenge of the Sith", 3, 0.75), (8-byte object <00-24 77-C6 35-27 05-00>, "The Force Awakens", 7, 0.8), (8-byte object <00-24 77-C6 35-27 05-00>, "The Force Awakens", 7, 0.8), (8-byte object <00-24 F0-A2 6A-60 05-00>, "The Last Jedi", 8, 0.1), (8-byte object <00-24 F0-A2 6A-60 05-00>, "The Last Jedi", 8, 0.1), (8-byte object <00-C4 4C-50 2C-9A 05-00>, "The Rise of Skywalker", 9, 0.3), (8-byte object <00-C4 4C-50 2C-9A 05-00>, "The Rise of Skywalker", 9, 0.3) }, which has 18 elements
[ FAILED ] TestSubspaceMsgMap.Basic (2 ms)
It would be useful, from a user stand-point to be able to get the client name from a Client. I have a PR for this, but I can't seem to be able to push the branch (maybe give me sufficient permissions?). Here is the diff:
--- a/client/client.cc
+++ b/client/client.cc
@@ -38,6 +38,7 @@ absl::Status Client::Init(const std::string &server_socket,
Request req;
req.mutable_init()->set_client_name(client_name);
+ name = client_name;
Response resp;
std::vector<toolbelt::FileDescriptor> fds;
fds.reserve(100);
diff --git a/client/client.h b/client/client.h
index add60fc..3b6fc81 100644
--- a/client/client.h
+++ b/client/client.h
@@ -16,6 +16,7 @@
#include "toolbelt/fd.h"
#include "toolbelt/sockets.h"
#include <functional>
+#include <string>
#include <sys/poll.h>
namespace subspace {
@@ -278,6 +279,9 @@ public:
// information unless you know how this works in detail.
void SetDebug(bool v) { debug_ = v; }
+ // Get the client's name, as given to the Init function.
+ const std::string& GetName() const { return name; }
+
private:
friend class Server;
friend class Publisher;
@@ -389,6 +393,7 @@ private:
int32_t new_slot_size);
absl::Status ReloadBuffersIfNecessary(details::ClientChannel *channel);
+ std::string name;
toolbelt::UnixSocket socket_;
toolbelt::FileDescriptor scb_fd_; // System control block memory fd.
char buffer_[kMaxMessage]; // Buffer for comms with server over UDS.
I'm not 100% sure what you prefer as a solution to this. Here is the problem:
I'm trying to use subspace subscribers and publishers, collect their fds from GetPollFd()
(which returns struct ::pollfd
), I then use them with coroutine::Wait
(which takes a vector of struct ::pollfd
), so far so good. But then, I also need to send them over UnixSocket::SendFds
(which takes a vector of toolbelt::FileDescriptor
). You see the issue, I cannot convert a struct ::pollfd
into a toolbelt::FileDescriptor
since that would close the fd on destruction.
There are a few solutions:
toolbelt::FileDescriptor
from GetPollFd
(or some differently named functions).toolbelt::FileDescriptor
similar to std::unique_ptr::release
that gives up ownership.UnixSocket::SendFds
to take int
fds, rather than demanding toolbelt::FileDescriptor
.Of course, all three could be done too. I think the last one is probably the most annoying and inefficient to implement.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.