1
0
Fork 0
forked from External/grumble

Use a transaction for UserList updates. Support delta-updates for UserState changes.

This commit is contained in:
Mikkel Krautz 2011-08-27 16:44:29 +02:00
parent c87329a344
commit 48efaf6645
2 changed files with 66 additions and 29 deletions

View file

@ -15,6 +15,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"strconv" "strconv"
"time"
) )
// Freeze a server to disk, and re-open the log, if needed. // Freeze a server to disk, and re-open the log, if needed.
@ -658,14 +659,37 @@ func NewServerFromFrozen(name string) (s *Server, err os.Error) {
} }
// Update the datastore with the user's current state. // Update the datastore with the user's current state.
func (server *Server) UpdateFrozenUser(user *User) { func (server *Server) UpdateFrozenUser(user *User, state *mumbleproto.UserState) {
fu, err := user.Freeze() // Full sync If there's no userstate messgae provided, or if there is one, and
if err != nil { // it includes a registration operation.
server.Fatal(err) nanos := time.Nanoseconds()
} if state == nil || state.UserId != nil {
err = server.freezelog.Put(fu) fu, err := user.Freeze()
if err != nil { if err != nil {
server.Fatal(err) server.Fatal(err)
}
fu.LastActive = proto.Uint64(uint64(nanos))
err = server.freezelog.Put(fu)
if err != nil {
server.Fatal(err)
}
} else {
fu := &freezer.User{}
fu.Id = proto.Uint32(user.Id)
if state.ChannelId != nil {
fu.LastChannelId = state.ChannelId
}
if state.TextureHash != nil {
fu.TextureBlob = proto.String(user.TextureBlob)
}
if state.CommentHash != nil {
fu.CommentBlob = proto.String(user.CommentBlob)
}
fu.LastActive = proto.Uint64(uint64(nanos))
err := server.freezelog.Put(fu)
if err != nil {
server.Fatal(err)
}
} }
server.numLogOps += 1 server.numLogOps += 1
} }

View file

@ -7,12 +7,13 @@ package main
import ( import (
"crypto/aes" "crypto/aes"
"crypto/tls" "crypto/tls"
"mumbleproto"
"goprotobuf.googlecode.com/hg/proto"
"net"
"fmt" "fmt"
"goprotobuf.googlecode.com/hg/proto"
"grumble/ban" "grumble/ban"
"grumble/blobstore" "grumble/blobstore"
"grumble/freezer"
"mumbleproto"
"net"
"time" "time"
) )
@ -916,7 +917,7 @@ func (server *Server) handleUserStateMessage(client *Client, msg *Message) {
} }
if target.IsRegistered() { if target.IsRegistered() {
server.UpdateFrozenUser(target.user) server.UpdateFrozenUser(target.user, userstate)
} }
} }
@ -1543,24 +1544,36 @@ func (server *Server) handleUserList(client *Client, msg *Message) {
} }
// Rename, registration removal // Rename, registration removal
} else { } else {
for _, listUser := range userlist.Users { if len(userlist.Users) > 0 {
uid := *listUser.UserId tx := server.freezelog.BeginTx()
if uid == 0 { for _, listUser := range userlist.Users {
continue uid := *listUser.UserId
} if uid == 0 {
user, ok := server.Users[uid] continue
if ok {
// De-register a user
if listUser.Name == nil {
server.RemoveRegistration(uid)
server.DeleteFrozenUser(user)
// Rename user
} else {
// todo(mkrautz): Validate name.
user.Name = *listUser.Name
server.UpdateFrozenUser(user)
} }
user, ok := server.Users[uid]
if ok {
if listUser.Name == nil {
// De-register
server.RemoveRegistration(uid)
err := tx.Put(&freezer.UserRemove{Id: listUser.UserId})
if err != nil {
server.Fatal(err)
}
} else {
// Rename user
// todo(mkrautz): Validate name.
user.Name = *listUser.Name
err := tx.Put(&freezer.User{Id: listUser.UserId, Name: listUser.Name})
if err != nil {
server.Fatal(err)
}
}
}
}
err := tx.Commit()
if err != nil {
server.Fatal(err)
} }
} }
} }