target.cc (1743B)
1 #include "storedip" 2 3 unsigned StoredIp::target(struct in_addr clientip, 4 BackendVector &targetlist) { 5 PROFILE("StoredIP::target"); 6 IPStore::on(); 7 8 msg("Starting stored-ip dispatcher\n"); 9 10 int tb; 11 if ( (tb = IPStore::target(clientip)) >= 0 ) { 12 unsigned target = tb; 13 IPStore::clear(clientip); 14 if (balancer.backend(target).available()) { 15 // Historical target is up, go there! 16 msg("Sending " << inet2string(clientip) << " to " << 17 balancer.backend(target).description() << '\n'); 18 return target; 19 } 20 msg ("Historical target " << 21 balancer.backend(target).description() << " unavailable\n"); 22 if (config.dispatchmode() == Dispatchmode::m_strict_stored_ip) 23 throw Error("Stored-IP algorithm: target back end " + 24 balancer.backend(target).description() + 25 " unavailable"); 26 } 27 28 // Client is seen for the first time, or after the timout period, or 29 // their preferred back end is down (and we're in lax mode ofc). 30 // Treat as new connection. 31 Leastconn l; 32 33 if (!config.removereservations()) 34 return l.target(clientip, targetlist); 35 else { 36 BackendVector tlist = targetlist; 37 while (true) { 38 try { 39 return l.target(clientip, tlist); 40 } catch (...) { 41 // We're out of back ends and need to clear up the IP store 42 // to retry. 43 // We give it a sec, remove the oldest entry, and rebuild the 44 // target list for the least-connections dispatch algorithm. 45 warnmsg("Out of back ends, releasing oldest client entry " 46 "and retrying\n"); 47 IPStore::clearoldest(); 48 sleep(1); 49 BackendVector newlist; 50 for (unsigned int i = 0; i < balancer.nbackends(); i++) 51 if (balancer.backend(i).available()) 52 newlist.add(i); 53 tlist = newlist; 54 } 55 } 56 } 57 } 58