// waitForPayloadDeath blocks until the payload process stored at anchor exits, for whatever reason. // anchor is the anchor path used by the virus logic. func waitFotPayloadDeath(c *client.Client, payloadAnchor string) (recov interface{}) { // defer func() { // catch panics caused by unexpected death of the server hosting the payload // recov = recover() // }() t := c.Walk(client.Split(payloadAnchor)) // Access the process anchor of the currently-running payload of the virus. t.Get().(client.Proc).Wait() // Wait until the payload process exits. t.Scrub() // scrub payload anchor from old process element time.Sleep(2 * time.Second) // Wait a touch to slow down the spin return }
// waitForPayloadDeath blocks until the payload process stored at anchor exits, for whatever reason. // anchor is the anchor path used by the virus logic. func waitFotPayloadDeath(c *client.Client, myAnchor, payloadAnchor string, epoch int) (recov interface{}) { // catch panics caused by unexpected death of the server hosting the payload defer func() { recov = recover() }() // Access the process anchor of the currently-running payload of the virus. t := c.Walk(client.Split(payloadAnchor)) // Wait until the payload process exits. t.Get().(client.Proc).Wait() // Remove the anchor of the now-dead payload process. // t.Scrub() // Wait a touch to prevent spinning, if the payload exits immediately every time it is run. time.Sleep(time.Second / 2) return }
// Create or get back channel func findBackChan(c *client.Client, isNucleus bool) (backAnchor string, backChan client.Chan) { var err error if isNucleus { // The nucleus does not proceed with execution until it acquires permission // to send the the virus' back channel. backAnchor = os.Args[2] backChan = c.Walk(client.Split(backAnchor)).Get().(client.Chan) } else { // Make the back channel backServer := pickServer(c) backChan, err = backServer.Walk([]string{"virus", "back"}).MakeChan(3) if err != nil { println(err.Error()) os.Exit(1) } backAnchor = path.Join("/", backServer.ServerID(), "virus", "back") } return }
func pickHosts(c *client.Client, n int) (hosts []client.Anchor) { defer func() { if recover() != nil { fatalf("client connection lost") } }() view := c.View() if len(view) == 0 { fatalf("no hosts in cluster") } for len(hosts) < n { for _, a := range view { if len(hosts) >= n { break } hosts = append(hosts, a) } } return }
// waitForPayloadDeath blocks until the payload process stored at anchor exits, for whatever reason. // anchor is the anchor path used by the virus logic. func waitFotPayloadDeath(c *client.Client, anchor string) { // catch panics caused by unexpected death of the server hosting the payload defer func() { recover() }() // Access the process anchor that started this very process and // remove it to make room for the new one. // Note that scrubbing a process anchor removes the process element, // but in no way affects the underlying OS process. walkToVirus := client.Split(anchor) c.Walk(append(walkToVirus, "nucleus")).Scrub() // Access the process anchor of the currently-running payload of the virus. t := c.Walk(append(walkToVirus, "payload")) // Wait until the payload process exits. t.Get().(client.Proc).Wait() // Remove the anchor of the now-dead payload process. t.Scrub() // Wait a touch to prevent spinning, if the payload exits immediately every time it is run. time.Sleep(time.Second / 2) }
// pickServer returns the root anchor of a randomly-chosen circuit server in the cluster. func pickServer(c *client.Client) client.Anchor { for _, r := range c.View() { return r } panic(0) }