예제 #1
0
// Actually only used for movie requests
vector<pair<char, string> > KeyValueStore::forwardLongRequest(Protocol::KEYVALUE_STORE type, const string& req, Config::ThreadControl& control)
{
  vector<pair<char, string> > ret;
  Mutex& outMutex = control.getOutMutex();
  Condition& cond = control.getOutCondition();

  procForward.lock();
  pair<char, string> freq(type, req);
  forwardQueue.enqueue(freq);
  
  outMutex.lock();
  cond.signal();
  outMutex.unlock();
  forwardCond.wait(procForward);

  while(true) {
    pair<char, string> resp(respBuffer.dequeue());
    ret.push_back(resp);
    if(resp.first == Protocol::MLOOKUP_DONE || resp.first == Protocol::LOOKUP_NO) {
      procForward.unlock();
      break;
    }
  }

  printKv("Done serving movie list");

  return ret;
}
예제 #2
0
pair<char, string> KeyValueStore::forwardRequest(Protocol::KEYVALUE_STORE type, const string& req, Config::ThreadControl& control)
{
  Mutex& outMutex = control.getOutMutex();
  Condition& cond = control.getOutCondition();

  procForward.lock();
  pair<char, string> freq(type, req);
  forwardQueue.enqueue(freq);
  outMutex.lock();
  cond.signal();
  outMutex.unlock();
  forwardCond.wait(procForward);
  pair<char, string> resp(respBuffer.dequeue());
  procForward.unlock();

  return resp;
}
예제 #3
0
void KeyValueStore::InternalThread::outgoingRoutine()
{
  unsigned currId = -1;
  const Config::ServerInformation& info = config.getServerInformation();
  Config::ThreadControl& control = config.getThreadControl();
  Mutex& outMutex = control.getOutMutex();
  Condition& cond = control.getOutCondition();
  Timespan timeout(3, 0); // 3 seconds to receive response
  bool connected = false;
  unsigned contentLength = 0;
  char* buf = NULL;

  while(control.isLive()) {
    outMutex.lock();
    cond.wait(outMutex);

    // Check if server changed
    if(control.getReconnectedTo()) {
      printKv("Reconnecting");
      currId = control.getConnectedToId();
      const Config::ServerInformation& nextInfo = config.getServerInformation(currId);
      try {
        if(connected)
          sock.close();
        sock.connect(SocketAddress(nextInfo.address, nextInfo.internalPort), Timespan(5, 0));
        connected = true;
        printKv("Connected to outgoing server: "<< nextInfo.id);
        //sock.setReceiveTimeout(timeout);
        KeyValueStore::replicateDB(sock, control.getMachineCount());
      } catch(Exception& e) {
        printKv("Could not connect to next key-value internal server ("<< e.displayText() <<")" << endl
          << "System may be inconsistent until next reconnect.");
        connected = false;
      }
    }

    while(!forwardQueue.isEmpty()) {
      pair<char, string> req(forwardQueue.dequeue());
      if(req.first == Protocol::REPL_INS || req.first == Protocol::REPL_REM) {
        try {
          KeyValueStore::sendRequest(sock, req);
        } catch(Exception& e) {
          printKv("Could not replicate: "<< e.displayText());
        }
      } else if(req.first == Protocol::INS_MOVIE) { // Requests without responses
        KeyValueStore::sendRequest(sock, req); // Not waiting for a response
      } else if(req.first == Protocol::LUP_MOVIE && false) { // This returns many responses need to get all
        printKv("Received movie lookup forward");
        KeyValueStore::sendRequest(sock, req);
        
        pair<char, string> resp(KeyValueStore::rcvResponse(sock, buf));
        while(resp.first != Protocol::MLOOKUP_DONE && resp.first != Protocol::LOOKUP_NO) {
          resp = KeyValueStore::rcvResponse(sock, buf);
          respBuffer.enqueue(resp);
//          replyForward(); // Send as we get them
        }
        respBuffer.enqueue(resp); // Make sure we also send our done response

        printKv("Served movies");

        replyForward();
      } else {
        // Forward and wait for response.
        try {
          KeyValueStore::sendRequest(sock, req);

          pair<char, string> resp(KeyValueStore::rcvResponse(sock, buf));
          respBuffer.enqueue(resp);

          replyForward();
        } catch(Exception& e) {
          // If we timeout or anything, treat request as failed
          printKv("Exception while forwarding: "<< e.displayText());
          respBuffer.enqueue(pair<char, string>(Protocol::REQ_FAIL, ""));
          replyForward();
        }
      }
    }
 //   if(!respBuffer.isEmpty())
   //   replyForward();

    outMutex.unlock();
  }
}