// Called before any command is issued by the client void CNSClientsRegistry::Touch(CNSClientId & client, TNSBitVector & running_jobs, TNSBitVector & reading_jobs, bool & client_was_found, bool & session_was_reset, string & old_session, bool & had_wn_pref_affs, bool & had_reader_pref_affs) { client_was_found = false; session_was_reset = false; old_session.clear(); had_wn_pref_affs = false; had_reader_pref_affs = false; // Check if it is an old-style client if (!client.IsComplete()) return; CMutexGuard guard(m_Lock); map< string, CNSClient >::iterator known_client = m_Clients.find(client.GetNode()); if (known_client == m_Clients.end()) { // The client is not known yet CNSClient new_ns_client(client, &m_BlacklistTimeout, &m_ReadBlacklistTimeout); unsigned int client_id = x_GetNextID(); new_ns_client.SetID(client_id); client.SetID(client_id); m_Clients[ client.GetNode() ] = new_ns_client; m_RegisteredClients.set_bit(client_id); return; } client_was_found = true; // The client has connected before client.SetID(known_client->second.GetID()); old_session = known_client->second.GetSession(); if (client.GetSession() != old_session) { session_was_reset = true; ClearClient(client, running_jobs, reading_jobs, client_was_found, old_session, had_wn_pref_affs, had_reader_pref_affs); } known_client->second.Touch(client); // The 'reset' client type must not reset the collected types when the next // command is issued if (client.GetType() == eClaimedReset) client.SetClientType(eClaimedAutodetect); }
// Used in the following situations: // - CLRN // - new session // - GC for a client (it is not strictly required because it may happened only // for inactive clients, i.e. timeouted or after CLRN void CNSClientsRegistry::ClearClient(const CNSClientId & client, TNSBitVector & running_jobs, TNSBitVector & reading_jobs, bool & client_was_found, string & old_session, bool & had_wn_pref_affs, bool & had_reader_pref_affs) { client_was_found = false; // Check if it is an old-style client if (client.IsComplete()) ClearClient(client.GetNode(), running_jobs, reading_jobs, client_was_found, old_session, had_wn_pref_affs, had_reader_pref_affs); }
int TLServer_IP::ServiceMessage(int MessageType, CString msg) { switch (MessageType) { case ORDERCANCELREQUEST : return CancelRequest((long)atoi(msg.GetBuffer())); case ACCOUNTREQUEST : return AccountResponse(msg); case CLEARCLIENT : return ClearClient(msg); case CLEARSTOCKS : return ClearStocks(msg); case REGISTERSTOCK : { vector<CString> rec; gsplit(msg,CString("+"),rec); CString client = rec[0]; vector<CString> hisstocks; // make sure client sent a basket, otherwise clear the basket if (rec.size()!=2) return ClearStocks(client); // get the basket gsplit(rec[1],CString(","),hisstocks); // make sure we have the client unsigned int cid = FindClient(client); if (cid==-1) return CLIENTNOTREGISTERED; //client not registered // save the basket stocks[cid] = hisstocks; D(CString(_T("Client ")+client+_T(" registered: ")+gjoin(hisstocks,","))); HeartBeat(client); return RegisterStocks(client); } case POSITIONREQUEST : { vector<CString> r; gsplit(msg,CString("+"),r); if (r.size()!=2) return UNKNOWN_MESSAGE; return PositionResponse(r[1],r[0]); } case REGISTERCLIENT : return RegisterClient(msg); case HEARTBEAT : return HeartBeat(msg); case BROKERNAME : return BrokerName(); case SENDORDER : return SendOrder(TLOrder::Deserialize(msg)); case FEATUREREQUEST: { // get features supported by child class std::vector<int> stub = GetFeatures(); // append basic feature we provide as parent stub.push_back(REGISTERCLIENT); stub.push_back(HEARTBEAT); stub.push_back(CLEARSTOCKS); stub.push_back(CLEARCLIENT); stub.push_back(VERSION); // send entire feature set back to client TLSend(FEATURERESPONSE,SerializeIntVec(stub),msg); return OK; } case VERSION : return MinorVer; } return UnknownMessage(MessageType,msg); }