Merge pull request #928 from birarda/assignment

couple of bugfixes for local stack assignment, UUID created with assignment
This commit is contained in:
ZappoMan 2013-09-12 17:11:45 -07:00
commit 11cc79fd41
5 changed files with 94 additions and 44 deletions

View file

@ -116,7 +116,7 @@ you likely had Cmake generate Xcode project files and have not run `cmake ..` in
Then, launch the static components - a domain-server and a voxel-server. All of the targets will run in the foreground, so you'll either want to background it yourself or open a seperate terminal window per target.
cd domain-server && ./domain-server --local
cd domain-server && ./domain-server
./voxel-server/voxel-server --local > /tmp/voxel-server.log 2>&1 &
Then, run an assignment-client with 2 forks to fulfill the avatar-mixer and audio-mixer assignments. It uses localhost as its assignment-server and talks to it on port 40102 (the default domain-server port).

View file

@ -51,27 +51,45 @@ unsigned char* addNodeToBroadcastPacket(unsigned char* currentPosition, Node* no
return currentPosition;
}
static int mongooseRequestHandler(struct mg_connection *conn) {
const struct mg_request_info *ri = mg_get_request_info(conn);
if (strcmp(ri->uri, "/assignment") == 0 && strcmp(ri->request_method, "POST") == 0) {
// return a 200
mg_printf(conn, "%s", "HTTP/1.0 200 OK\r\n\r\n");
// upload the file
mg_upload(conn, "/tmp");
return 1;
} else {
// have mongoose process this request from the document_root
return 0;
}
}
const char ASSIGNMENT_SCRIPT_HOST_LOCATION[] = "web/assignment";
static void mongooseUploadHandler(struct mg_connection *conn, const char *path) {
// create an assignment for this saved script
Assignment scriptAssignment(Assignment::CreateCommand, Assignment::AgentType);
QString newPath(ASSIGNMENT_SCRIPT_HOST_LOCATION);
newPath += "/";
// append the UUID for this script as the new filename, remove the curly braces
newPath += scriptAssignment.getUUID().toString().mid(1, scriptAssignment.getUUID().toString().length() - 2);
// rename the saved script to the GUID of the assignment and move it to the script host locaiton
rename(path, newPath.toStdString().c_str());
qDebug("Saved a script for assignment at %s\n", newPath.toStdString().c_str());
}
int main(int argc, const char* argv[]) {
qInstallMessageHandler(Logging::verboseMessageHandler);
NodeList* nodeList = NodeList::createInstance(NODE_TYPE_DOMAIN, DOMAIN_LISTEN_PORT);
// If user asks to run in "local" mode then we do NOT replace the IP
// with the EC2 IP. Otherwise, we will replace the IP like we used to
// this allows developers to run a local domain without recompiling the
// domain server
bool isLocalMode = cmdOptionExists(argc, (const char**) argv, "--local");
if (isLocalMode) {
printf("NOTE: Running in local mode!\n");
} else {
printf("--------------------------------------------------\n");
printf("NOTE: Not running in local mode. \n");
printf("If you're a developer testing a local system, you\n");
printf("probably want to include --local on command line.\n");
printf("--------------------------------------------------\n");
}
setvbuf(stdout, NULL, _IOLBF, 0);
ssize_t receivedBytes = 0;
@ -82,7 +100,7 @@ int main(int argc, const char* argv[]) {
unsigned char* currentBufferPos;
unsigned char* startPointer;
sockaddr_in nodePublicAddress, nodeLocalAddress;
sockaddr_in nodePublicAddress, nodeLocalAddress, replyDestinationSocket;
nodeLocalAddress.sin_family = AF_INET;
in_addr_t serverLocalAddress = getLocalAddress();
@ -128,7 +146,10 @@ int main(int argc, const char* argv[]) {
// list of options. Last element must be NULL.
const char *options[] = {"listening_ports", "8080",
"document_root", "./web", NULL};
"document_root", "./web", NULL};
callbacks.begin_request = mongooseRequestHandler;
callbacks.upload = mongooseUploadHandler;
// Start the web server.
ctx = mg_start(&callbacks, NULL, options);
@ -161,19 +182,15 @@ int main(int argc, const char* argv[]) {
int numBytesSocket = unpackSocket(packetData + numBytesSenderHeader + sizeof(NODE_TYPE),
(sockaddr*) &nodeLocalAddress);
sockaddr* destinationSocket = (sockaddr*) &nodePublicAddress;
replyDestinationSocket = nodePublicAddress;
// check the node public address
// if it matches our local address we're on the same box
// so hardcode the EC2 public address for now
if (nodePublicAddress.sin_addr.s_addr == serverLocalAddress) {
// If we're not running "local" then we do replace the IP
// with 0. This designates to clients that the server is reachable
// at the same IP address
if (!isLocalMode) {
nodePublicAddress.sin_addr.s_addr = 0;
destinationSocket = (sockaddr*) &nodeLocalAddress;
}
// if it matches our local address
// or if it's the loopback address we're on the same box
if (nodePublicAddress.sin_addr.s_addr == serverLocalAddress ||
nodePublicAddress.sin_addr.s_addr == htonl(INADDR_LOOPBACK)) {
nodePublicAddress.sin_addr.s_addr = 0;
}
Node* newNode = nodeList->addOrUpdateNode((sockaddr*) &nodePublicAddress,
@ -244,7 +261,7 @@ int main(int argc, const char* argv[]) {
currentBufferPos += packNodeId(currentBufferPos, newNode->getNodeID());
// send the constructed list back to this node
nodeList->getNodeSocket()->send(destinationSocket,
nodeList->getNodeSocket()->send((sockaddr*)&replyDestinationSocket,
broadcastPacket,
(currentBufferPos - startPointer) + numHeaderBytes);
}

View file

@ -12,20 +12,28 @@ $(document).ready(function(){
$('#deploy-button').click(function(){
script = editor.getValue();
// store the script on S3 using filepicker
filepicker.store(script, {mimetype: 'application/javascript'}, function(blob){
console.log(JSON.stringify(blob));
s3_filename = blob["key"];
$.post('/assignment', {s3_filename: s3_filename}, function(response){
// the response is the assignment ID, if successful
console.log(response);
}, function(error) {
console.log(error);
});
}, function(FPError){
console.log(FPError);
// setup our boundary - this is "highfidelity" in hex
var boundary = "----68696768666964656c697479";
var body = '--' + boundary + '\r\n'
// parameter name is "file" and local filename is "temp.txt"
+ 'Content-Disposition:form-data; name="file"; '
+ 'filename="script.js"\r\n'
// add the javascript mime-type
+ 'Content-type: application/javascript\r\n\r\n'
// add the script
+ script + '\r\n'
+ '--' + boundary + '--';
// post form to assignment in order to create an assignment
$.ajax({
contentType: "multipart/form-data; boundary=" + boundary,
data: body,
type: "POST",
url: "/assignment",
success: function (data, status) {
console.log(data);
console.log(status);
}
});
});
});

View file

@ -7,12 +7,15 @@
//
#include "PacketHeaders.h"
#include "SharedUtil.h"
#include "Assignment.h"
const char IPv4_ADDRESS_DESIGNATOR = 4;
const char IPv6_ADDRESS_DESIGNATOR = 6;
const int NUM_BYTES_RFC4122_UUID = 16;
Assignment::Assignment(Assignment::Command command, Assignment::Type type, Assignment::Location location) :
_command(command),
_type(type),
@ -22,6 +25,11 @@ Assignment::Assignment(Assignment::Command command, Assignment::Type type, Assig
{
// set the create time on this assignment
gettimeofday(&_time, NULL);
if (_command == Assignment::CreateCommand) {
// this is a newly created assignment, generate a random UUID
_uuid = QUuid::createUuid();
}
}
Assignment::Assignment(const unsigned char* dataBuffer, int numBytes) :
@ -44,6 +52,12 @@ Assignment::Assignment(const unsigned char* dataBuffer, int numBytes) :
numBytesRead += numBytesForPacketHeader(dataBuffer);
if (dataBuffer[0] != PACKET_TYPE_REQUEST_ASSIGNMENT) {
// read the GUID for this assignment
_uuid = QUuid::fromRfc4122(QByteArray((const char*) dataBuffer + numBytesRead, NUM_BYTES_RFC4122_UUID));
numBytesRead += NUM_BYTES_RFC4122_UUID;
}
memcpy(&_type, dataBuffer + numBytesRead, sizeof(Assignment::Type));
numBytesRead += sizeof(Assignment::Type);
@ -102,6 +116,12 @@ void Assignment::setAttachedLocalSocket(const sockaddr* attachedLocalSocket) {
int Assignment::packToBuffer(unsigned char* buffer) {
int numPackedBytes = 0;
// pack the UUID for this assignment, if this is an assignment create or deploy
if (_command != Assignment::RequestCommand) {
memcpy(buffer, _uuid.toRfc4122().constData(), NUM_BYTES_RFC4122_UUID);
numPackedBytes += NUM_BYTES_RFC4122_UUID;
}
memcpy(buffer + numPackedBytes, &_type, sizeof(_type));
numPackedBytes += sizeof(_type);

View file

@ -11,6 +11,8 @@
#include <sys/time.h>
#include <QtCore/QUuid>
#include "NodeList.h"
/// Holds information used for request, creation, and deployment of assignments
@ -20,6 +22,7 @@ public:
enum Type {
AudioMixerType,
AvatarMixerType,
AgentType,
AllTypes
};
@ -45,6 +48,7 @@ public:
~Assignment();
const QUuid& getUUID() const { return _uuid; }
Assignment::Command getCommand() const { return _command; }
Assignment::Type getType() const { return _type; }
Assignment::Location getLocation() const { return _location; }
@ -65,6 +69,7 @@ public:
void setCreateTimeToNow() { gettimeofday(&_time, NULL); }
private:
QUuid _uuid; /// the 16 byte UUID for this assignment
Assignment::Command _command; /// the command for this assignment (Create, Deploy, Request)
Assignment::Type _type; /// the type of the assignment, defines what the assignee will do
Assignment::Location _location; /// the location of the assignment, allows a domain to preferentially use local ACs