Assignment as LinkedData, add back to queue on node death

This commit is contained in:
Stephen Birarda 2013-09-30 11:04:42 -07:00
parent fce97e2754
commit a8d55644e9
4 changed files with 49 additions and 16 deletions

View file

@ -78,6 +78,27 @@ void DomainServer::nodeAdded(Node* node) {
} }
void DomainServer::nodeKilled(Node* node) { void DomainServer::nodeKilled(Node* node) {
// if this node has linked data it was from an assignment
if (node->getLinkedData()) {
Assignment* nodeAssignment = (Assignment*) node->getLinkedData();
// find this assignment in the static file
for (int i = 0; i < MAX_STATIC_ASSIGNMENT_FILE_ASSIGNMENTS; i++) {
if (_staticAssignments[i].getUUID() == nodeAssignment->getUUID()) {
// reset the UUID on the static assignment
_staticAssignments[i].resetUUID();
// put this assignment back in the queue so it goes out
_assignmentQueueMutex.lock();
_assignmentQueue.push_back(&_staticAssignments[i]);
_assignmentQueueMutex.unlock();
} else if (_staticAssignments[i].getUUID().isNull()) {
// we are at the blank part of the static assignments - break out
break;
}
}
}
} }
@ -170,7 +191,7 @@ void DomainServer::prepopulateStaticAssignmentFile() {
_staticAssignmentFile.close(); _staticAssignmentFile.close();
} }
int DomainServer::checkInMatchesStaticAssignment(NODE_TYPE nodeType, const uchar* checkInData) { int DomainServer::indexForMatchingStaticAssignment(NODE_TYPE nodeType, const uchar* checkInData) {
// pull the UUID passed with the check in // pull the UUID passed with the check in
QUuid checkInUUID = QUuid::fromRfc4122(QByteArray((const char*) checkInData + numBytesForPacketHeader(checkInData) + QUuid checkInUUID = QUuid::fromRfc4122(QByteArray((const char*) checkInData + numBytesForPacketHeader(checkInData) +
sizeof(NODE_TYPE), sizeof(NODE_TYPE),
@ -178,8 +199,8 @@ int DomainServer::checkInMatchesStaticAssignment(NODE_TYPE nodeType, const uchar
int staticAssignmentIndex = 0; int staticAssignmentIndex = 0;
while (staticAssignmentIndex < MAX_STATIC_ASSIGNMENT_FILE_ASSIGNMENTS while (staticAssignmentIndex < MAX_STATIC_ASSIGNMENT_FILE_ASSIGNMENTS
&& !_staticFileAssignments[staticAssignmentIndex].getUUID().isNull()) { && !_staticAssignments[staticAssignmentIndex].getUUID().isNull()) {
Assignment* staticAssignment = &_staticFileAssignments[staticAssignmentIndex]; Assignment* staticAssignment = &_staticAssignments[staticAssignmentIndex];
if (staticAssignment->getType() == Assignment::typeForNodeType(nodeType) if (staticAssignment->getType() == Assignment::typeForNodeType(nodeType)
&& staticAssignment->getUUID() == checkInUUID) { && staticAssignment->getUUID() == checkInUUID) {
@ -279,7 +300,7 @@ int DomainServer::run() {
_staticAssignmentFileData = _staticAssignmentFile.map(0, _staticAssignmentFile.size()); _staticAssignmentFileData = _staticAssignmentFile.map(0, _staticAssignmentFile.size());
_numAssignmentsInStaticFile = (uint16_t*) _staticAssignmentFileData; _numAssignmentsInStaticFile = (uint16_t*) _staticAssignmentFileData;
_staticFileAssignments = (Assignment*) _staticAssignments = (Assignment*)
(_staticAssignmentFileData + sizeof(*_numAssignmentsInStaticFile)); (_staticAssignmentFileData + sizeof(*_numAssignmentsInStaticFile));
while (true) { while (true) {
@ -314,12 +335,18 @@ int DomainServer::run() {
int matchingStaticAssignmentIndex = -1; int matchingStaticAssignmentIndex = -1;
if (memchr(STATICALLY_ASSIGNED_NODES, nodeType, sizeof(STATICALLY_ASSIGNED_NODES)) == NULL || if (memchr(STATICALLY_ASSIGNED_NODES, nodeType, sizeof(STATICALLY_ASSIGNED_NODES)) == NULL ||
(matchingStaticAssignmentIndex = checkInMatchesStaticAssignment(nodeType, packetData)) != -1) { (matchingStaticAssignmentIndex = indexForMatchingStaticAssignment(nodeType, packetData)) != -1) {
Node* checkInNode = nodeList->addOrUpdateNode((sockaddr*) &nodePublicAddress, Node* checkInNode = nodeList->addOrUpdateNode((sockaddr*) &nodePublicAddress,
(sockaddr*) &nodeLocalAddress, (sockaddr*) &nodeLocalAddress,
nodeType, nodeType,
nodeList->getLastNodeID()); nodeList->getLastNodeID());
if (matchingStaticAssignmentIndex != -1) {
// set the linked data for this node to the matching assignment from the static file
// so we can re-queue it should the node die
checkInNode->setLinkedData(&_staticAssignments[matchingStaticAssignmentIndex]);
}
int numHeaderBytes = populateTypeAndVersion(broadcastPacket, PACKET_TYPE_DOMAIN); int numHeaderBytes = populateTypeAndVersion(broadcastPacket, PACKET_TYPE_DOMAIN);
@ -327,8 +354,8 @@ int DomainServer::run() {
startPointer = currentBufferPos; startPointer = currentBufferPos;
int numBytesUUID = (nodeType == NODE_TYPE_AUDIO_MIXER || nodeType == NODE_TYPE_AVATAR_MIXER) int numBytesUUID = (nodeType == NODE_TYPE_AUDIO_MIXER || nodeType == NODE_TYPE_AVATAR_MIXER)
? NUM_BYTES_RFC4122_UUID ? NUM_BYTES_RFC4122_UUID
: 0; : 0;
unsigned char* nodeTypesOfInterest = packetData + numBytesSenderHeader + numBytesUUID + unsigned char* nodeTypesOfInterest = packetData + numBytesSenderHeader + numBytesUUID +
sizeof(NODE_TYPE) + numBytesSocket + sizeof(unsigned char); sizeof(NODE_TYPE) + numBytesSocket + sizeof(unsigned char);
@ -398,8 +425,11 @@ int DomainServer::run() {
// find the first available spot in the static assignments and put this assignment there // find the first available spot in the static assignments and put this assignment there
for (int i = 0; i < MAX_STATIC_ASSIGNMENT_FILE_ASSIGNMENTS; i++) { for (int i = 0; i < MAX_STATIC_ASSIGNMENT_FILE_ASSIGNMENTS; i++) {
if (_staticFileAssignments[i].getUUID().isNull()) { if (_staticAssignments[i].getUUID().isNull()) {
_staticFileAssignments[i] = *createAssignment; _staticAssignments[i] = *createAssignment;
// we've stuck the assignment in, break out
break;
} }
} }
} }

View file

@ -42,7 +42,7 @@ private:
static DomainServer* domainServerInstance; static DomainServer* domainServerInstance;
void prepopulateStaticAssignmentFile(); void prepopulateStaticAssignmentFile();
int checkInMatchesStaticAssignment(NODE_TYPE nodeType, const uchar* checkInUUID); int indexForMatchingStaticAssignment(NODE_TYPE nodeType, const uchar* checkInUUID);
Assignment* deployableAssignmentForRequest(Assignment& requestAssignment); Assignment* deployableAssignmentForRequest(Assignment& requestAssignment);
void cleanup(); void cleanup();
@ -56,7 +56,7 @@ private:
uchar* _staticAssignmentFileData; uchar* _staticAssignmentFileData;
uint16_t* _numAssignmentsInStaticFile; uint16_t* _numAssignmentsInStaticFile;
Assignment* _staticFileAssignments; Assignment* _staticAssignments;
const char* _voxelServerConfig; const char* _voxelServerConfig;
}; };

View file

@ -19,7 +19,7 @@ const int NUM_BYTES_RFC4122_UUID = 16;
const int MAX_PAYLOAD_BYTES = 1024; const int MAX_PAYLOAD_BYTES = 1024;
/// Holds information used for request, creation, and deployment of assignments /// Holds information used for request, creation, and deployment of assignments
class Assignment : public QObject { class Assignment : public NodeData {
Q_OBJECT Q_OBJECT
public: public:
@ -79,6 +79,9 @@ public:
/// \return number of bytes packed into buffer /// \return number of bytes packed into buffer
int packToBuffer(unsigned char* buffer); int packToBuffer(unsigned char* buffer);
// implement parseData to return 0 so we can be a subclass of NodeData
int parseData(unsigned char* sourceBuffer, int numBytes) { return 0; }
/// blocking run of the assignment /// blocking run of the assignment
virtual void run(); virtual void run();

View file

@ -16,7 +16,7 @@ class Node;
class NodeData : public QObject { class NodeData : public QObject {
Q_OBJECT Q_OBJECT
public: public:
NodeData(Node* owningNode); NodeData(Node* owningNode = NULL);
virtual ~NodeData() = 0; virtual ~NodeData() = 0;
virtual int parseData(unsigned char* sourceBuffer, int numBytes) = 0; virtual int parseData(unsigned char* sourceBuffer, int numBytes) = 0;