dispatch.cc (2126B)
1 #include "tcpdispatcher" 2 3 void TcpDispatcher::dispatch() { 4 // Check that a working algorithm is available. May be missing if 5 // constructor's "new" failed. 6 if (!algorithm()) 7 throw Error("No algorithm in Tcpdispatcher::dispatch"); 8 9 bool connected = false; 10 11 // Build up the target list, if not yet done so. The HTTP dispatcher 12 // might've created it already for host-based matching (in which case 13 // we won't bother here). 14 if (! targetlist().isdefined()) { 15 msg("Creating target list for the TCP dispatcher\n"); 16 for (unsigned i = 0; i < balancer.nbackends(); i++) 17 if (balancer.backend(i).available()) { 18 targetlist().add(i); 19 if (config.verbose()) 20 msg(" Candidate target: " << 21 balancer.backend(i).description() << '\n'); 22 } 23 } 24 25 // Call the dispatch algorithm until we can connect, 26 // or until the algorithm is out of back ends (throws exception). 27 while (!connected) { 28 targetbackend(algorithm()->target(clientfd().clientaddr().sin_addr, 29 targetlist())); 30 31 // Define a dummy back end according to the current selection. 32 // Connect to it. If that succeeds, get the socket from it. 33 Backend tb; 34 tb.server(balancer.backend(targetbackend()).server()); 35 tb.port(balancer.backend(targetbackend()).port()); 36 37 if (!tb.connect()) { 38 balancer.backend(targetbackend()).live(false); 39 if (config.verbose()) 40 msg("Failed to connect to back end " << tb.description() << 41 ", trying to dispatch to other\n"); 42 // Re-evaluate back ends. Something may have come online. 43 msg("Re-creating target list for the TCP dispatcher.\n"); 44 targetlist().reset(); 45 for (unsigned i = 0; i < balancer.nbackends(); i++) 46 if (balancer.backend(i).available()) { 47 targetlist().add(i); 48 if (config.verbose()) 49 msg(" Candidate target: " << 50 balancer.backend(i).description() << '\n'); 51 } 52 // And now fall thru into the next loop run... 53 } else { 54 connected = true; 55 backendfd(tb.sock()); 56 msg ("Will dispatch client to back end " << tb.description() << 57 " on fd " << tb.sock().fd() << '\n'); 58 break; 59 } 60 } 61 }