func (fs *FS) CreateFile(anchor string, owner circuit.Addr) error { // Probably should save addr using durable-like techniques var w bytes.Buffer if err := gob.NewEncoder(&w).Encode(&ZFile{owner}); err != nil { panic(err) } parts, _, err := anchorfs.Sanitize(anchor) if err != nil { return err } _anchor := path.Join(append([]string{fs.root}, parts...)...) println(_anchor) if err = zutil.CreateRecursive(fs.zookeeper, _anchor, zutil.PermitAll); err != nil { return err } _, err = fs.zookeeper.Create( path.Join(_anchor, owner.WorkerID().String()), string(w.Bytes()), zookeeper.EPHEMERAL, zutil.PermitAll, ) if err != nil { return err } fs.Lock() defer fs.Unlock() fs.created[anchor] = struct{}{} return nil }
// exportPtr returns *permPtrMsg if importer is nil, and *ptrMsg otherwise. func (r *Runtime) exportPtr(v interface{}, importer circuit.Addr) interface{} { // Add exported value to export table exph := r.exp.Add(v, importer) if importer == nil { return &permPtrMsg{ID: exph.ID, TypeID: exph.Type.ID} } // Monitor the importer for liveness. // DropPtr the handles upon importer death. r.lk.Lock() defer r.lk.Unlock() _, ok := r.live[importer] if !ok { r.live[importer] = struct{}{} // The anonymous function creates a "lifeline" connection to the worker importing v. // When this conncetion is broken, v is released. go func() { // Defer removal of v's handle from the export table to the end of this function defer func() { r.lk.Lock() delete(r.live, importer) r.lk.Unlock() // DropPtr/forget all exported handles r.exp.RemoveImporter(importer) }() conn, err := r.dialer.Dial(importer) if err != nil { println("problem dialing lifeline to", importer.String(), err.Error()) return } defer conn.Close() if conn.Write(&dontReplyMsg{}) != nil { println("problem writing on lifeline to", importer.String(), err.Error()) return } // Read returns when the remote dies and // runs the conn into an error conn.Read() }() } return &ptrMsg{ID: exph.ID, TypeID: exph.Type.ID} }
func tailViaSSH(addr circuit.Addr, jailpath string) { abs := path.Join(config.Config.Install.JailDir(), addr.WorkerID().String(), jailpath) cmd := exec.Command("ssh", addr.Host(), "tail -f "+abs) stdout, err := cmd.StdoutPipe() if err != nil { println("Pipe problem:", err.Error()) os.Exit(1) } if err = cmd.Start(); err != nil { println("Exec problem:", err.Error()) os.Exit(1) } io.Copy(os.Stdout, stdout) }
func getReducerTop(addr circuit.Addr, lk *sync.Mutex, top *SortablePosts) { // Obtain cross-runtime pointer to reducer service on the worker owning file f x, err := circuit.TryDial(addr, "reducer-service") if err != nil { println("dial", addr.String(), "error", err.Error()) // Skip reducers that seem to be dead return } // Catch panics due to dead worker and return empty list of top ten posts in this case defer func() { if p := recover(); p != nil { fmt.Fprintf(os.Stderr, "%s.Top panic: %#v\n", x.String(), p) } }() // Fetch top ten posts rtop := x.Call("Top")[0].([]*Post) lk.Lock() defer lk.Unlock() println("Reducer", addr.String(), "contributed", len(rtop), "posts") (*top) = append(*top, rtop...) }