func (session *pcpBalancingSession) HandleServerFault() (*balancer.BackendServer, error) { // Fencing: Stop the original node just to be sure. // TODO more reliable fencing. session.backgroundStopRemote() // Check preconditions for failover sending := session.balancingSession.SendingSession sending2, ok := sending.(*balancer.BalancingSession) ampSession, ok2 := sending2.Handler.(*ampBalancingSession) if !ok || !ok2 { return nil, fmt.Errorf("Can only handle PCP fault when sending session is *ampBalancingSession. Instead have %v (%T)", sending, sending) } // Find and initialize backup server var usedBackup *balancer.BackendServer var pcpBackup *pcp.Client var resp *pcp.StartProxyPairResponse for _, backup := range session.balancingSession.BackupServers { var err error pcpBackup, err = pcp.NewClient(backup.Client) // TODO log errors that prevented a backup server from being used? if err == nil { var err error proxyHost := pcpBackup.Server().IP().String() // TODO The proxyHost could be different. See the comment above in NewSession. resp, err = pcpBackup.StartProxyPair(proxyHost, session.receiverHost, session.receiverPort, session.receiverPort+1) if err == nil { usedBackup = backup break } } } if usedBackup == nil { return nil, fmt.Errorf("No valid backup server for %s!", session.client) } session.client = pcpBackup session.proxyHost = resp.ProxyHost session.proxyPort = resp.ProxyPort1 // Try to redirect the stream to the new proxy. err := ampSession.RedirectStream(resp.ProxyHost, resp.ProxyPort1) if err != nil { return nil, err } return usedBackup, nil }
func closeProxyPCP(client *pcp.Client, listenPort, targetPort int) { golib.Printerr(client.StopProxy(pcpProxyAddrs(listenPort, targetPort))) }
func makeProxyPCP(client *pcp.Client, listenPort, targetPort int) { golib.Checkerr(client.StartProxy(pcpProxyAddrs(listenPort, targetPort))) }