mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 16:18:05 +02:00
Merge pull request #952 from birarda/assignment
Assignment improvements
This commit is contained in:
commit
268248f5e3
7 changed files with 20 additions and 191 deletions
|
@ -14,7 +14,6 @@ set(CMAKE_AUTOMOC ON)
|
||||||
|
|
||||||
add_subdirectory(animation-server)
|
add_subdirectory(animation-server)
|
||||||
add_subdirectory(assignment-client)
|
add_subdirectory(assignment-client)
|
||||||
add_subdirectory(assignment-server)
|
|
||||||
add_subdirectory(domain-server)
|
add_subdirectory(domain-server)
|
||||||
add_subdirectory(eve)
|
add_subdirectory(eve)
|
||||||
add_subdirectory(interface)
|
add_subdirectory(interface)
|
||||||
|
|
|
@ -78,7 +78,7 @@ void childClient() {
|
||||||
// construct the deployed assignment from the packet data
|
// construct the deployed assignment from the packet data
|
||||||
Assignment* deployedAssignment = AssignmentFactory::unpackAssignment(packetData, receivedBytes);
|
Assignment* deployedAssignment = AssignmentFactory::unpackAssignment(packetData, receivedBytes);
|
||||||
|
|
||||||
qDebug() << "Received an assignment -" << deployedAssignment << "\n";
|
qDebug() << "Received an assignment -" << *deployedAssignment << "\n";
|
||||||
|
|
||||||
// switch our nodelist DOMAIN_IP
|
// switch our nodelist DOMAIN_IP
|
||||||
if (packetData[0] == PACKET_TYPE_CREATE_ASSIGNMENT ||
|
if (packetData[0] == PACKET_TYPE_CREATE_ASSIGNMENT ||
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
cmake_minimum_required(VERSION 2.8)
|
|
||||||
|
|
||||||
set(TARGET_NAME assignment-server)
|
|
||||||
|
|
||||||
set(ROOT_DIR ..)
|
|
||||||
set(MACRO_DIR ${ROOT_DIR}/cmake/macros)
|
|
||||||
|
|
||||||
include(${MACRO_DIR}/SetupHifiProject.cmake)
|
|
||||||
setup_hifi_project(${TARGET_NAME} TRUE)
|
|
||||||
|
|
||||||
# link in the shared library
|
|
||||||
include(${MACRO_DIR}/LinkHifiLibrary.cmake)
|
|
||||||
link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR})
|
|
|
@ -1,117 +0,0 @@
|
||||||
//
|
|
||||||
// main.cpp
|
|
||||||
// assignment-server
|
|
||||||
//
|
|
||||||
// Created by Stephen Birarda on 7/1/13.
|
|
||||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <fstream>
|
|
||||||
#include <deque>
|
|
||||||
|
|
||||||
#include <QtCore/QString>
|
|
||||||
|
|
||||||
#include <Assignment.h>
|
|
||||||
#include <Logging.h>
|
|
||||||
#include <PacketHeaders.h>
|
|
||||||
#include <SharedUtil.h>
|
|
||||||
#include <UDPSocket.h>
|
|
||||||
|
|
||||||
const int MAX_PACKET_SIZE_BYTES = 1400;
|
|
||||||
const long long NUM_DEFAULT_ASSIGNMENT_STALENESS_USECS = 10 * 1000 * 1000;
|
|
||||||
|
|
||||||
int main(int argc, const char* argv[]) {
|
|
||||||
|
|
||||||
qInstallMessageHandler(Logging::verboseMessageHandler);
|
|
||||||
|
|
||||||
std::deque<Assignment*> assignmentQueue;
|
|
||||||
|
|
||||||
sockaddr_in senderSocket;
|
|
||||||
unsigned char senderData[MAX_PACKET_SIZE_BYTES] = {};
|
|
||||||
ssize_t receivedBytes = 0;
|
|
||||||
|
|
||||||
UDPSocket serverSocket(ASSIGNMENT_SERVER_PORT);
|
|
||||||
|
|
||||||
unsigned char assignmentPacket[MAX_PACKET_SIZE_BYTES];
|
|
||||||
int numSendHeaderBytes = populateTypeAndVersion(assignmentPacket, PACKET_TYPE_DEPLOY_ASSIGNMENT);
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
if (serverSocket.receive((sockaddr*) &senderSocket, &senderData, &receivedBytes)) {
|
|
||||||
if (senderData[0] == PACKET_TYPE_REQUEST_ASSIGNMENT) {
|
|
||||||
// construct the requested assignment from the packet data
|
|
||||||
Assignment requestAssignment(senderData, receivedBytes);
|
|
||||||
|
|
||||||
qDebug() << "Received request for assignment:" << requestAssignment << "\n";
|
|
||||||
qDebug() << "Current queue size is" << assignmentQueue.size() << "\n";
|
|
||||||
|
|
||||||
// make sure there are assignments in the queue at all
|
|
||||||
if (assignmentQueue.size() > 0) {
|
|
||||||
|
|
||||||
std::deque<Assignment*>::iterator assignment = assignmentQueue.begin();
|
|
||||||
|
|
||||||
// enumerate assignments until we find one to give this client (if possible)
|
|
||||||
while (assignment != assignmentQueue.end()) {
|
|
||||||
|
|
||||||
// if this assignment is stale then get rid of it and check the next one
|
|
||||||
if (usecTimestampNow() - usecTimestamp(&((*assignment)->getTime()))
|
|
||||||
>= NUM_DEFAULT_ASSIGNMENT_STALENESS_USECS) {
|
|
||||||
delete *assignment;
|
|
||||||
assignment = assignmentQueue.erase(assignment);
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (requestAssignment.getType() == Assignment::AllTypes ||
|
|
||||||
(*assignment)->getType() == requestAssignment.getType()) {
|
|
||||||
// give this assignment out, either we have a type match or the requestor has said they will
|
|
||||||
// take all types
|
|
||||||
|
|
||||||
// check if the requestor is on the same network as the destination for the assignment
|
|
||||||
if (senderSocket.sin_addr.s_addr ==
|
|
||||||
((sockaddr_in*) (*assignment)->getAttachedPublicSocket())->sin_addr.s_addr) {
|
|
||||||
// if this is the case we remove the public socket on the assignment by setting it to NULL
|
|
||||||
// this ensures the local IP and port sent to the requestor is the local address of destination
|
|
||||||
(*assignment)->setAttachedPublicSocket(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int numAssignmentBytes = (*assignment)->packToBuffer(assignmentPacket + numSendHeaderBytes);
|
|
||||||
|
|
||||||
// send the assignment
|
|
||||||
serverSocket.send((sockaddr*) &senderSocket,
|
|
||||||
assignmentPacket,
|
|
||||||
numSendHeaderBytes + numAssignmentBytes);
|
|
||||||
|
|
||||||
|
|
||||||
// delete this assignment now that it has been sent out
|
|
||||||
delete *assignment;
|
|
||||||
// remove it from the deque and make the iterator the next assignment
|
|
||||||
assignmentQueue.erase(assignment);
|
|
||||||
|
|
||||||
// stop looping - we've handed out an assignment
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
// push forward the iterator to check the next assignment
|
|
||||||
assignment++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (senderData[0] == PACKET_TYPE_CREATE_ASSIGNMENT && packetVersionMatch(senderData)) {
|
|
||||||
// construct the create assignment from the packet data
|
|
||||||
Assignment* createdAssignment = new Assignment(senderData, receivedBytes);
|
|
||||||
|
|
||||||
qDebug() << "Received a created assignment:" << *createdAssignment << "\n";
|
|
||||||
qDebug() << "Current queue size is" << assignmentQueue.size() << "\n";
|
|
||||||
|
|
||||||
// assignment server is likely on a public server
|
|
||||||
// assume that the address we now have for the sender is the public address/port
|
|
||||||
// and store that with the assignment so it can be given to the requestor later if necessary
|
|
||||||
createdAssignment->setAttachedPublicSocket((sockaddr*) &senderSocket);
|
|
||||||
|
|
||||||
// add this assignment to the queue
|
|
||||||
assignmentQueue.push_back(createdAssignment);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -134,18 +134,6 @@ int main(int argc, const char* argv[]) {
|
||||||
nodeList->startSilentNodeRemovalThread();
|
nodeList->startSilentNodeRemovalThread();
|
||||||
|
|
||||||
timeval lastStatSendTime = {};
|
timeval lastStatSendTime = {};
|
||||||
const char ASSIGNMENT_SERVER_OPTION[] = "-a";
|
|
||||||
|
|
||||||
// grab the overriden assignment-server hostname from argv, if it exists
|
|
||||||
const char* customAssignmentServer = getCmdOption(argc, argv, ASSIGNMENT_SERVER_OPTION);
|
|
||||||
if (customAssignmentServer) {
|
|
||||||
sockaddr_in customAssignmentSocket = socketForHostnameAndHostOrderPort(customAssignmentServer, ASSIGNMENT_SERVER_PORT);
|
|
||||||
nodeList->setAssignmentServerSocket((sockaddr*) &customAssignmentSocket);
|
|
||||||
}
|
|
||||||
|
|
||||||
// use a map to keep track of iterations of silence for assignment creation requests
|
|
||||||
const long long GLOBAL_ASSIGNMENT_REQUEST_INTERVAL_USECS = 1 * 1000 * 1000;
|
|
||||||
timeval lastGlobalAssignmentRequest = {};
|
|
||||||
|
|
||||||
// as a domain-server we will always want an audio mixer and avatar mixer
|
// as a domain-server we will always want an audio mixer and avatar mixer
|
||||||
// setup the create assignments for those
|
// setup the create assignments for those
|
||||||
|
@ -415,50 +403,19 @@ int main(int argc, const char* argv[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
::assignmentQueueMutex.unlock();
|
::assignmentQueueMutex.unlock();
|
||||||
}
|
} else if (packetData[0] == PACKET_TYPE_CREATE_ASSIGNMENT) {
|
||||||
}
|
// this is a create assignment likely recieved from a server needed more clients to help with load
|
||||||
|
|
||||||
// if ASSIGNMENT_REQUEST_INTERVAL_USECS have passed since last global assignment request then fire off another
|
|
||||||
if (usecTimestampNow() - usecTimestamp(&lastGlobalAssignmentRequest) >= GLOBAL_ASSIGNMENT_REQUEST_INTERVAL_USECS) {
|
|
||||||
gettimeofday(&lastGlobalAssignmentRequest, NULL);
|
|
||||||
|
|
||||||
::assignmentQueueMutex.lock();
|
|
||||||
|
|
||||||
// go through our queue and see if there are any assignments to send to the global assignment server
|
|
||||||
std::deque<Assignment*>::iterator assignment = ::assignmentQueue.begin();
|
|
||||||
|
|
||||||
while (assignment != assignmentQueue.end()) {
|
|
||||||
|
|
||||||
if ((*assignment)->getLocation() != Assignment::LocalLocation) {
|
// unpack it
|
||||||
// attach our local socket to the assignment so the assignment-server can optionally hand it out
|
Assignment* createAssignment = new Assignment(packetData, receivedBytes);
|
||||||
(*assignment)->setAttachedLocalSocket((sockaddr*) &localSocket);
|
|
||||||
|
qDebug() << "Received a create assignment -" << *createAssignment << "\n";
|
||||||
nodeList->sendAssignment(*(*assignment));
|
|
||||||
|
// add the assignment at the back of the queue
|
||||||
if ((*assignment)->getType() == Assignment::AgentType) {
|
::assignmentQueueMutex.lock();
|
||||||
// if this is a script assignment we need to delete it to avoid a memory leak
|
::assignmentQueue.push_back(createAssignment);
|
||||||
// or if there is more than one instance to send out, simpy decrease the number of instances
|
::assignmentQueueMutex.unlock();
|
||||||
if ((*assignment)->getNumberOfInstances() > 1) {
|
|
||||||
(*assignment)->decrementNumberOfInstances();
|
|
||||||
} else {
|
|
||||||
::assignmentQueue.erase(assignment);
|
|
||||||
delete *assignment;
|
|
||||||
}
|
|
||||||
} else if ((*assignment)->getType() == Assignment::VoxelServerType) {
|
|
||||||
// this is a voxel server assignment
|
|
||||||
// remove the assignment from the queue
|
|
||||||
::assignmentQueue.erase(assignment);
|
|
||||||
}
|
|
||||||
|
|
||||||
// stop looping, we've handed out an assignment
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
// push forward the iterator to check the next assignment
|
|
||||||
assignment++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
::assignmentQueueMutex.unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Logging::shouldSendStats()) {
|
if (Logging::shouldSendStats()) {
|
||||||
|
|
|
@ -88,21 +88,21 @@ Assignment::Assignment(const unsigned char* dataBuffer, int numBytes) :
|
||||||
|
|
||||||
if (numBytes > numBytesRead) {
|
if (numBytes > numBytesRead) {
|
||||||
_numPayloadBytes = numBytes - numBytesRead;
|
_numPayloadBytes = numBytes - numBytesRead;
|
||||||
memcpy(_payload, dataBuffer + numBytesRead, numBytes - numBytesRead);
|
_payload = new uchar[_numPayloadBytes];
|
||||||
|
memcpy(_payload, dataBuffer + numBytesRead, _numPayloadBytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Assignment::~Assignment() {
|
Assignment::~Assignment() {
|
||||||
delete _attachedPublicSocket;
|
delete _attachedPublicSocket;
|
||||||
delete _attachedLocalSocket;
|
delete _attachedLocalSocket;
|
||||||
delete _payload;
|
delete[] _payload;
|
||||||
_numPayloadBytes = 0;
|
_numPayloadBytes = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int MAX_PAYLOAD_BYTES = 1024;
|
const int MAX_PAYLOAD_BYTES = 1024;
|
||||||
|
|
||||||
void Assignment::setPayload(uchar* payload, int numBytes) {
|
void Assignment::setPayload(const uchar* payload, int numBytes) {
|
||||||
_payload = payload;
|
|
||||||
|
|
||||||
if (numBytes > MAX_PAYLOAD_BYTES) {
|
if (numBytes > MAX_PAYLOAD_BYTES) {
|
||||||
qDebug("Set payload called with number of bytes greater than maximum (%d). Will only transfer %d bytes.\n",
|
qDebug("Set payload called with number of bytes greater than maximum (%d). Will only transfer %d bytes.\n",
|
||||||
|
@ -114,6 +114,9 @@ void Assignment::setPayload(uchar* payload, int numBytes) {
|
||||||
_numPayloadBytes = numBytes;
|
_numPayloadBytes = numBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete[] _payload;
|
||||||
|
_payload = new uchar[_numPayloadBytes];
|
||||||
|
memcpy(_payload, payload, _numPayloadBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Assignment::getUUIDStringWithoutCurlyBraces() const {
|
QString Assignment::getUUIDStringWithoutCurlyBraces() const {
|
||||||
|
|
|
@ -61,7 +61,7 @@ public:
|
||||||
|
|
||||||
uchar* getPayload() { return _payload; }
|
uchar* getPayload() { return _payload; }
|
||||||
int getNumPayloadBytes() const { return _numPayloadBytes; }
|
int getNumPayloadBytes() const { return _numPayloadBytes; }
|
||||||
void setPayload(uchar *payload, int numBytes);
|
void setPayload(const uchar *payload, int numBytes);
|
||||||
|
|
||||||
int getNumberOfInstances() const { return _numberOfInstances; }
|
int getNumberOfInstances() const { return _numberOfInstances; }
|
||||||
void setNumberOfInstances(int numberOfInstances) { _numberOfInstances = numberOfInstances; }
|
void setNumberOfInstances(int numberOfInstances) { _numberOfInstances = numberOfInstances; }
|
||||||
|
|
Loading…
Reference in a new issue