Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 2 commits
  • 3 files changed
  • 0 commit comments
  • 1 contributor
Commits on Jul 09, 2012
Alexis Sellier cloudhead Ensure all tickets have a unique id
This solves a race condition where two tickets
could end up with the same ID.
2fcb66f
Alexis Sellier cloudhead Test parallel ticket creation 5e27fec
Showing with 52 additions and 7 deletions.
  1. +11 −0 snapshot.go
  2. +12 −4 ticket.go
  3. +29 −3 ticket_test.go
11 snapshot.go
View
@@ -129,3 +129,14 @@ func GetLatest(s Snapshot, path string, codec Codec) (file *File, err error) {
return
}
+
+// Getuid returns a unique ID from the coordinator
+func Getuid(s Snapshot) (rev int64, err error) {
+ for {
+ rev, err = s.conn.Set("/uid", -1, []byte{})
+ if err != doozer.ErrOldRev {
+ break
+ }
+ }
+ return
+}
16 ticket.go
View
@@ -75,7 +75,7 @@ const (
// procType
func CreateTicket(appName string, revName string, pName ProcessName, op OperationType, s Snapshot) (t *Ticket, err error) {
t = &Ticket{
- Id: s.Rev,
+ Id: -1,
AppName: appName,
RevisionName: revName,
ProcessName: pName,
@@ -87,16 +87,24 @@ func CreateTicket(appName string, revName string, pName ProcessName, op Operatio
return t.Create()
}
-func (t *Ticket) Create() (*Ticket, error) {
+func (t *Ticket) Create() (tt *Ticket, err error) {
+ tt = t
+
+ id, err := Getuid(t.Snapshot)
+ if err != nil {
+ return
+ }
+ t.Id = id
+
f, err := CreateFile(t.Snapshot, t.prefixPath("op"), t.toArray(), new(ListCodec))
if err != nil {
- return t, err
+ return
}
f, err = CreateFile(t.Snapshot, t.prefixPath("status"), string(t.Status), new(StringCodec))
if err == nil {
t.Snapshot = t.Snapshot.FastForward(f.Rev)
}
- return t, err
+ return
}
// Claims returns the list of claimers
32 ticket_test.go
View
@@ -6,6 +6,7 @@
package visor
import (
+ "fmt"
"os"
"strconv"
"testing"
@@ -28,6 +29,32 @@ func ticketSetup() (s Snapshot, hostname string) {
return
}
+func TestTicketCreateTickets(t *testing.T) {
+ s, _ := ticketSetup()
+
+ c := make(chan bool)
+
+ for i := 0; i < 10; i++ {
+ go func() {
+ _, err := CreateTicket("lol", "cat", "app", OpStart, s)
+ if err != nil {
+ t.Error(err)
+ }
+ c <- true
+ }()
+ }
+ for i := 0; i < 10; i++ {
+ <-c
+ }
+
+ rev, _ := s.conn.Rev()
+ dir, _ := s.conn.Getdir("/tickets", rev)
+
+ if len(dir) != 10 {
+ t.Errorf("tick creation failed: %d", len(dir))
+ }
+}
+
func TestTicketCreateTicket(t *testing.T) {
s, _ := ticketSetup()
@@ -49,7 +76,6 @@ func TestTicketCreateTicket(t *testing.T) {
func TestTicketClaim(t *testing.T) {
s, host := ticketSetup()
- id := s.Rev
ticket, err := CreateTicket("claim", "abcd123", "test", OpStart, s)
if err != nil {
@@ -61,7 +87,7 @@ func TestTicketClaim(t *testing.T) {
t.Error(err)
}
- status, _, err := ticket.conn.Get("tickets/"+strconv.FormatInt(id, 10)+"/status", &ticket.Rev)
+ status, _, err := ticket.conn.Get(fmt.Sprintf("tickets/%d/status", ticket.Id), &ticket.Rev)
if err != nil {
t.Error(err)
}
@@ -69,7 +95,7 @@ func TestTicketClaim(t *testing.T) {
t.Error("Ticket not claimed")
}
- exists, _, err := ticket.conn.Exists("tickets/" + strconv.FormatInt(id, 10) + "/claims/" + host)
+ exists, _, err := ticket.conn.Exists(fmt.Sprintf("tickets/%d/claims/%s", ticket.Id, host))
if !exists {
t.Error(err)
}

No commit comments for this range

Something went wrong with that request. Please try again.