func (self *permaNode) applyMutation(newnode *mutationNode, transformer Transformer) (err os.Error) { if transformer == nil { return } // Find out how far back we have to go in history to find a common anchor point for transformation h := ot.NewHistoryGraph(self.frontier, newnode.Dependencies()) prune := map[string]bool{} rollback := int64(0) // Need to rollback? if !h.Test() { // Go back in history until our history is equal to (or earlier than) that of 'mut'. // On the way remember which mutations of our history do not belong to the // history of 'mut' because these must be pruned. ch, err := self.grapher.getOTNodesDescending(self.BlobRef()) if err != nil { return err } for history_node := range ch { if !h.SubstituteBlob(history_node.BlobRef(), history_node.Dependencies()) { prune[history_node.BlobRef()] = true } rollback++ if h.Test() { break } } } concurrent := []string{} for c, _ := range prune { concurrent = append(concurrent, c) } ch, err := self.grapher.getMutationsAscending(self.blobref, newnode.EntityBlobRef(), newnode.Field(), self.SequenceNumber()-rollback, self.SequenceNumber()) if err != nil { return err } err = transformer.TransformMutation(newnode, ch, concurrent) if err != nil { return err } return }
func (self *Grapher) handleKeep(perma *permaNode, keep *keepNode) bool { var perm *permissionNode // The signer of the keep is not the signer of the permanode? // In this case he must present a valid invitation if keep.Signer() != perma.Signer() { var err os.Error perm, err = self.permission(perma.BlobRef(), keep.permissionBlobRef) if err != nil || perm == nil { // Problem already catched at checkKeep panic("Keep references a permision that is something else or malformed") } } // This keep is new. The permaNode has a new user. perma.addKeep(keep.Signer()) log.Printf("Processing keep of %v\n", keep.Signer()) // Signal the keep to the application if self.api != nil { if perm != nil { self.api.Blob_Keep(perma, perm, keep) } else { self.api.Blob_Keep(perma, nil, keep) } } // This implies that the local user is accepting an invitation? if perm != nil && perm.User == self.userID { // Send the keep (which accepts the invitation) to the signer of the invitation if self.fed != nil && keep.Signer() != self.userID { self.fed.Forward(keep.BlobRef(), []string{keep.Signer()}) } // self.openInvitations[perma.BlobRef()] = "", false log.Printf("The local user accepted the invitation\nREF=%v\n", keep.BlobRef()) } else if perm != nil { // Some other user is accepting his invitation? log.Printf("The user %v accepted the invitation\n", keep.Signer()) // Send this user all blobs of the local user that are not in the other user's frontier yet. if self.fed != nil { h := ot.NewHistoryGraph(perma.frontier, keep.Dependencies()) h.SubstituteBlob(keep.BlobRef(), keep.Dependencies()) forwards := []string{} if !h.Test() { ch, _ := self.getOTNodesDescending(perma.BlobRef()) for history_node := range ch { if !h.SubstituteBlob(history_node.BlobRef(), history_node.Dependencies()) { // Send nodes created by the local user if history_node.Signer() == self.userID { forwards = append(forwards, history_node.BlobRef()) // Send keeps that rely on a permission given by the local user } else if k, ok := history_node.(*keepNode); ok && k.permissionBlobRef != "" { if p, e := self.permission(perma.BlobRef(), k.permissionBlobRef); e == nil && p != nil && p.Signer() == self.userID { forwards = append(forwards, history_node.BlobRef()) } } } if h.Test() { break } } } for _, f := range forwards { self.fed.Forward(f, []string{keep.Signer()}) } } } return true }
func (self *Indexer) handleKeep(perma *PermaNode, keep *keepNode) bool { log.Printf("Handling Keep from %v at %v\n", keep.Signer(), self.userID) var perm *permissionNode // The signer of the keep is not the signer of the permanode? // In this case he must present a valid invitation if keep.Signer() != perma.Signer() { var err os.Error perm, err = self.Permission(keep.permission) if err != nil || perm == nil { // Problem already catched at checkKeep panic("Keep references a permision that is something else or malformed") } } // Does this implicitly accept a pending invitation? Clean it up. if _, ok := perma.pendingInvitations[keep.Signer()]; ok { perma.pendingInvitations[keep.Signer()] = "", false } // This keep is new. The permaNode has a new user. perma.keeps[keep.Signer()] = keep.BlobRef() // This implies accepting an invitation? if perm != nil && perm.permission.User == self.userID { // Send the keep (which accepts the invitation) to the signer of the invitation if self.fed != nil && keep.Signer() != self.userID { self.fed.Forward(keep.BlobRef(), []string{keep.Signer()}) } self.openInvitations[perma.BlobRef()] = "", false log.Printf("The local user accepted the invitation\n") // Signal this to the application for _, app := range self.appIndexers { app.PermaNode(perma.BlobRef(), perm.BlobRef(), keep.BlobRef()) } } else { if perm != nil { log.Printf("The user %v accepted the invitation\n", keep.Signer()) // Signal this to the application for _, app := range self.appIndexers { app.NewFollower(perma.BlobRef(), perm.BlobRef(), keep.BlobRef(), perm.permission.User) } // Send this user all blobs of the local user that are not in the other user's frontier yet. if perma.ot != nil && self.fed != nil { frontier := perma.ot.Frontier() h := ot.NewHistoryGraph(frontier, keep.Dependencies()) forwards := []string{} if !h.Test() { for x := range perma.ot.History(true) { history_node := x.(otNode) if !h.SubstituteBlob(history_node.BlobRef(), history_node.Dependencies()) { // Send nodes created by the local user if history_node.Signer() == self.userID { forwards = append(forwards, history_node.BlobRef()) // Send keeps that rely on a permission given by the local user } else if k, ok := x.(*keepNode); ok && k.permission != "" { if p, e := self.Permission(k.permission); e == nil && p != nil && p.Signer() == self.userID { forwards = append(forwards, history_node.BlobRef()) } } } if h.Test() { break } } } for _, f := range forwards { self.fed.Forward(f, []string{keep.Signer()}) } } } else { log.Printf("The user %v keeps his own perma node\n", keep.Signer()) // Signal this to the application for _, app := range self.appIndexers { app.PermaNode(perma.BlobRef(), "", keep.BlobRef()) } } } return true }
func (self *permaNode) applyPermission(newnode *permissionNode) (err os.Error) { // Find out how far back we have to go in history to find a common anchor point for transformation h := ot.NewHistoryGraph(self.frontier, newnode.Dependencies()) reverse_permissions := []*permissionNode{} prune := map[string]bool{} // Need to rollback? if !h.Test() { // Go back in history until our history is equal to (or earlier than) that of 'mut'. // On the way remember which mutations of our history do not belong to the // history of 'mut' because these must be pruned. ch, err := self.grapher.getOTNodesDescending(self.BlobRef()) if err != nil { return err } for history_node := range ch { if !h.SubstituteBlob(history_node.BlobRef(), history_node.Dependencies()) { prune[history_node.BlobRef()] = true } if x, ok := history_node.(*permissionNode); ok { reverse_permissions = append(reverse_permissions, x) } if h.Test() { break } } } // Reverse the mutation history, such that oldest are first in the list. // This is ugly but prepending in the above loops is too slow. permissions := make([]*permissionNode, len(reverse_permissions)) for i := 0; i < len(permissions); i++ { permissions[i] = reverse_permissions[len(reverse_permissions)-1-i] } // Prune all mutations that have been applied locally but do not belong to the history of the new mutation pnodes, e := prunePermissionSeq(permissions, prune) if e != nil { log.Printf("Prune Error: %v\n", e) err = e return } // Transform 'newnode' to apply it locally pnodes = append(pnodes, newnode) for _, n := range permissions { if n.BlobRef() != pnodes[0].BlobRef() { pnodes, _, err = transformPermissionSeq(pnodes, n) if err != nil { log.Printf("TRANSFORM ERR: %v", err) return } } else { pnodes = pnodes[1:] } } *newnode = *pnodes[0] bits, ok := self.permissions[newnode.User] if !ok { bits = 0 } bits, err = ot.ExecutePermission(bits, newnode.Permission) if err == nil { self.permissions[newnode.User] = bits } return }
func (self *otHistory) Apply(newnode otNode) (deps []string, err os.Error) { // The mutation has already been applied? if self.HasApplied(newnode.BlobRef()) { return } // Are all dependencies satisfied, i.e. are all mutations // on which mut depends already processed by the builder? unsatisfied := false for _, dep := range newnode.Dependencies() { if !self.HasApplied(dep) { unsatisfied = true deps = append(deps, dep) } } if unsatisfied { return deps, nil } // Find out how far back we have to go in history to find a common anchor point for transformation frontier := self.Frontier() h := ot.NewHistoryGraph(frontier, newnode.Dependencies()) reverse_nodes := []otNode{} prune := map[string]bool{} // Need to rollback? if !h.Test() { // Go back in history until our history is equal to (or earlier than) that of 'mut'. // On the way remember which mutations of our history do not belong to the // history of 'mut' because these must be pruned. for x := range self.History(true) { history_node := x.(otNode) if !h.SubstituteBlob(history_node.BlobRef(), history_node.Dependencies()) { prune[history_node.BlobRef()] = true } reverse_nodes = append(reverse_nodes, history_node) if h.Test() { break } } } // Reverse the mutation history, such that oldest are first in the list. // This is ugly but prepending in the above loops is too slow. nodes := make([]otNode, len(reverse_nodes)) for i := 0; i < len(nodes); i++ { nodes[i] = reverse_nodes[len(reverse_nodes)-1-i] } // Prune all mutations that have been applied locally but do not belong to the history of the new mutation pnodes, e := pruneSeq(nodes, prune) if e != nil { log.Printf("Prune Error: %v\n", e) err = e return } // Transform 'mut' to apply it locally pnodes = append(pnodes, newnode) for _, n := range nodes { if n.BlobRef() != pnodes[0].BlobRef() { pnodes, _, err = transformSeq(pnodes, n) if err != nil { log.Printf("TRANSFORM ERR: %v", err) return } } else { pnodes = pnodes[1:] } } newnode = pnodes[0] // Apply the mutation if mut, ok := newnode.(*mutationNode); ok { mut.mutation.AppliedAt = len(self.appliedBlobs) } self.appliedBlobs = append(self.appliedBlobs, newnode.BlobRef()) self.members[newnode.BlobRef()] = newnode self.frontier.AddBlob(newnode.BlobRef(), newnode.Dependencies()) if mut, ok := newnode.(*mutationNode); ok { self.content, err = ot.Execute(self.content, mut.mutation) } else if perm, ok := newnode.(*permissionNode); ok { bits, ok := self.permissions[perm.permission.User] if !ok { bits = 0 } bits, err = ot.ExecutePermission(bits, perm.permission) if err == nil { self.permissions[perm.permission.User] = bits } } return }