Support reconnecting to agents

Agents do not die immediately on disconnect anymore. Instead, agent_id
is sent at birth and can be sent during negotiation to attach to a
disconnected agent.
This commit is contained in:
Petr Baudis 2011-12-08 02:01:56 +01:00
parent 417a5235a0
commit 8ae6051e97
4 changed files with 52 additions and 7 deletions

19
README
View file

@ -20,6 +20,9 @@ CRLF ("\r\n"), not just LF ("\n")!
The following inputs (in no particular order) are supported:
agent_id <id>
unique id of agent; may be sent only once at the beginning
(you can use it to reconnect to the same agent later)
tick <ticknum>
BUMP
if received, the agent's move failed
@ -62,9 +65,10 @@ The following outputs are supported:
energy required is proportional to phintensity
After connecting, the client specifies its desired attributes,
in the same format as in normal output (line-based, terminated
by empty line), but with these commands instead:
When new agent connects, the client first enters the "negotiation"
phase, specifying its desired attributes, in the same format as in
normal output (line-based, terminated by empty line), but with
these commands instead:
move <rate>
<rate> between 0 and 1, describing probability
@ -76,3 +80,12 @@ by empty line), but with these commands instead:
In general, higher rate means higher energy maintenance of the
appropriate actuators.
Alternately, the client may send a single command in the negotiation
phase:
agent_id <id>
If the id corresponds to a disconnected agent, the connection
is immediately attached to that agent. Combining this with other
negotiation commands is undefined.

View file

@ -126,7 +126,6 @@ agent::on_action_takes(void)
return;
if (conn->error) {
if (!dead) die();
conn->cancel();
conn = NULL;
return;

View file

@ -143,9 +143,14 @@ $socket = IO::Socket::INET->new(
print "[ii] connected\r\n";
# negotiate attributs
print $socket "move 1.0\r\n";
print $socket "attack 1.0\r\n";
print $socket "defense 1.0\r\n";
if ($ARGV[1]) {
print "[ii] recovering agent $ARGV[1]\r\n";
print $socket "agent_id $ARGV[1]\r\n";
} else {
print $socket "move 1.0\r\n";
print $socket "attack 1.0\r\n";
print $socket "defense 1.0\r\n";
}
print $socket "\r\n";
print "[ii] agent created\r\n";

View file

@ -2,6 +2,7 @@
#include <cstdio>
#include <cstring>
#include <iostream>
#include <sstream>
#include <sys/select.h>
#include <pthread.h>
@ -9,6 +10,7 @@
#include "agent.h"
#include "connection.h"
#include "main.h"
#define buf_incomplete(buf) \
(buf.find("\r\n") == std::string::npos || (buf.find("\r\n") > 0 && buf.find("\r\n\r\n") == std::string::npos))
@ -120,6 +122,28 @@ connection::actions(class agent &agent)
if (rate >= 0 && rate <= 1)
agent.attr.defense = rate;
} else if (negotiation && !cmd.compare("agent_id")) {
int id = -1;
sscanf(line.c_str(), "%d", &id);
if (id < 0) {
bump_negot:
bump(); out_buf.append("\r\n");
} else {
class agent *a2 = NULL;
for (std::list<class agent *>::iterator ai = agents.begin(); ai != agents.end(); ai++) {
if ((*ai)->id == id) {
a2 = *ai;
break;
}
}
if (!a2 || a2->conn || !a2->tile || (dynamic_cast<herb *> (a2)))
goto bump_negot;
/* Round and round she goes, where she stops, nobody knows. */
a2->conn = this;
agent.conn = NULL;
negotiation = false;
}
} else if (!negotiation && !cmd.compare("move_dir") && !(mask & 1)) {
int x = 0, y = 0;
sscanf(line.c_str(), "%d %d", &x, &y);
@ -154,6 +178,10 @@ connection::actions(class agent &agent)
if (negotiation) {
negotiation = false;
agent.spawn();
std::stringstream s;
s << "agent_id " << agent.id << "\r\n";
out_buf.append(s.str());
}
pthread_mutex_unlock(&buf_lock);