You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by be...@apache.org on 2011/06/05 07:24:21 UTC
svn commit: r1131741 - in /incubator/mesos/trunk/src/third_party/libprocess:
reliable.cpp reliable.hpp
Author: benh
Date: Sun Jun 5 05:24:21 2011
New Revision: 1131741
URL: http://svn.apache.org/viewvc?rev=1131741&view=rev
Log:
Preliminary implementation of ReliableProcess for sending reliable messages.
Added:
incubator/mesos/trunk/src/third_party/libprocess/reliable.cpp
incubator/mesos/trunk/src/third_party/libprocess/reliable.hpp
Added: incubator/mesos/trunk/src/third_party/libprocess/reliable.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/third_party/libprocess/reliable.cpp?rev=1131741&view=auto
==============================================================================
--- incubator/mesos/trunk/src/third_party/libprocess/reliable.cpp (added)
+++ incubator/mesos/trunk/src/third_party/libprocess/reliable.cpp Sun Jun 5 05:24:21 2011
@@ -0,0 +1,143 @@
+#include "reliable.hpp"
+
+#define TIMEOUT 10
+
+
+class ReliableSender : public Process
+{
+public:
+ int seq;
+ struct msg *msg;
+ PID via;
+
+ ReliableSender(int _seq, struct msg *_msg, const PID& _via = PID())
+ : seq(_seq), msg(_msg), via(_via) {}
+
+protected:
+ void operator () ()
+ {
+ do {
+ if (via == PID()) {
+ fatal("unimplemented");
+ //string data = pack<RELIABLE_MSG>(seq, msg);
+ send(msg->to, RELIABLE_MSG, data.data(), data.size());
+ } else {
+ fatal("unimplemented");
+ //string data = pack<RELIABLE_RELAY>(seq, msg);
+ send(via, RELIABLE_RELAY, data.data(), data.size());
+ }
+
+ switch (receive(TIMEOUT)) {
+ case RELIABLE_ACK: {
+ // All done!
+ return;
+ }
+ case RELIABLE_REDIRECT: {
+ const PID &pid = *static_cast<const PID *>(body());
+ msg->to = pid;
+ break;
+ }
+ case PROCESS_TIMEOUT: {
+ // Retry!
+ break;
+ }
+ }
+ } while (true);
+ }
+};
+
+
+ReliableProcess::ReliableProcess() : seq(0) {}
+
+
+ReliableProcess::~ReliableProcess() {}
+
+
+void ReliableProcess::redirect(const PID &old, const PID &cur)
+{
+ // Send a redirect to all running senders and update internal mapping.
+ foreachpair (const PID &pid, ReliableSender *sender, senders) {
+ // TODO(benh): Don't look into sender's class like this ... HACK!
+ if (old == sender->msg->to) {
+ assert(pid, sender->getPID());
+ send(pid, RELIABLE_REDIRECT, &cur, sizeof(PID));
+ }
+ }
+}
+
+
+void ReliableProcess::rsend(const PID &to, MSGID id, const char *data, size_t length)
+{
+ // Allocate/Initialize outgoing message.
+ struct msg *msg = (struct msg *) malloc(sizeof(struct msg) + length);
+
+ msg->from.pipe = self().pipe;
+ msg->from.ip = self().ip;
+ msg->from.port = self().port;
+ msg->to.pipe = to.pipe;
+ msg->to.ip = to.ip;
+ msg->to.port = to.port;
+ msg->id = id;
+ msg->len = length;
+
+ if (length > 0)
+ memcpy((char *) msg + sizeof(struct msg), data, length);
+
+ ReliableSender *sender = new ReliableSender(seq++, msg);
+ PID pid = link(spawn(sender));
+ senders[pid] = sender;
+}
+
+
+void ReliableProcess::relay(const PID &via, const PID &to, MSGID id, const char *data, size_t length)
+{
+ // Allocate/Initialize outgoing message.
+ struct msg *msg = (struct msg *) malloc(sizeof(struct msg) + length);
+
+ msg->from.pipe = self().pipe;
+ msg->from.ip = self().ip;
+ msg->from.port = self().port;
+ msg->to.pipe = to.pipe;
+ msg->to.ip = to.ip;
+ msg->to.port = to.port;
+ msg->id = id;
+ msg->len = length;
+
+ if (length > 0)
+ memcpy((char *) msg + sizeof(struct msg), data, length);
+
+ ReliableSender *sender = new ReliableSender(seq++, msg, via);
+ PID pid = link(spawn(sender));
+ senders[pid] = sender;
+}
+
+
+MSGID ReliableProcess::receive(time_t secs)
+{
+ do {
+ MSGID id = Process::receive(secs);
+ switch (id) {
+ case RELIABLE_MSG: {
+ send(from(), RELIABLE_ACK);
+ const struct msg *msg = static_cast<const struct msg *>(body());
+ inject(msg->from, msg->id, body() + sizeof(struct msg), msg->len);
+ return Process::receive();
+ }
+ case RELIABLE_RELAY: {
+ const struct msg *msg = static_cast<const struct msg *>(body());
+ inject(msg->from, msg->id, body() + sizeof(struct msg), msg->len);
+ return Process::receive();
+ }
+ case PROCESS_EXIT: {
+ if (senders.find(from()) != senders.end()) {
+ ReliableSender *sender = senders[from()];
+ senders.erase(from());
+ delete sender;
+ continue;
+ }
+ break;
+ }
+ }
+ return id;
+ } while (true);
+}
Added: incubator/mesos/trunk/src/third_party/libprocess/reliable.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/third_party/libprocess/reliable.hpp?rev=1131741&view=auto
==============================================================================
--- incubator/mesos/trunk/src/third_party/libprocess/reliable.hpp (added)
+++ incubator/mesos/trunk/src/third_party/libprocess/reliable.hpp Sun Jun 5 05:24:21 2011
@@ -0,0 +1,68 @@
+#ifndef __RELIABLE_HPP__
+#define __RELIABLE_HPP__
+
+#include <process.hpp>
+
+
+class ReliableSender;
+
+
+class ReliableProcess : public Process
+{
+public:
+ Reliable();
+ ~Reliable();
+
+protected:
+ /**
+ * Update PID 'old' to 'cur' so that unsent messages will be
+ * redirected appropriately.
+ * @param old the existing PID
+ * @param cur the new PID
+ */
+ virtual void redirect(const PID &old, const PID &cur);
+
+ /**
+ * Sends a _reliable_ message to PID.
+ * @param to destination
+ * @param id message id
+ */
+ virtual void rsend(const PID &to, MSGID id);
+
+ /**
+ * Sends a _reliable_ message with data to PID.
+ * @param to destination
+ * @param id message id
+ * @param data payload
+ * @param length payload length
+ */
+ virtual void rsend(const PID &to, MSGID id, const char *data, size_t length);
+
+ virtual void relay(const PID &via, const PID &to, MSGID id);
+
+ virtual void relay(const PID &via, const PID &to, MSGID id, const char *data, size_t length);
+
+ virtual bool duplicate() const;
+
+ /* Blocks for message at most specified seconds. */
+ virtual MSGID receive(time_t);
+
+private:
+ int seq;
+ std::map<PID, ReliableSender *> senders;
+};
+
+
+inline void ReliableProcess::rsend(const PID &to, MSGID id)
+{
+ rsend(to, id, NULL, 0);
+}
+
+
+inline void ReliableProcess::relay(const PID &via, const PID &to, MSGID id)
+{
+ relay(via, to, id, NULL, 0);
+}
+
+
+#endif /* __RELIABLE_HPP__ */