func (p *DataStoreHandler) makeConnection() { // Only make once if p.connection.Client != nil { return } var err error p.connection, err = etcdMisc.MakeEtcdConnection(&http.Client{Timeout: 0}, nil, "http", p.etcdAddr, p.etcdPort) if err != nil { logger.Printf("Failed to connect to etcd: %s", err) } }
func main() { connection, err := etcdMisc.MakeEtcdConnection(&http.Client{Timeout: 0}, nil, "http", "localhost", 4001) fmt.Printf("Connection: %s\n", connection) // --------------------------------------------------------------------------------------------------- // Protective Delete of a directory, might be non-existant r, err := connection.DeleteDir("/junk", true) if err != nil { fmt.Println("Failed to delete directory:", err) } else { fmt.Printf("Deleted directory: %s\n", r) } // Start making a directory r, err = connection.Mkdir("/junk") if err != nil { fmt.Println("Failed to create directory:", err) os.Exit(-1) } fmt.Printf("Created directory successfully: %s\n", r) // Add to the previous directory r, err = connection.Mkdir("/junk/one") if err != nil { fmt.Println("Failed to create directory:", err) os.Exit(-1) } fmt.Printf("Created directory successfully: %s\n", r) // --------------------------------------------------------------------------------------------------- // Set followed by a 'Get' to verify r, err = connection.SetValue("/junk/blob1", "Hello") if err != nil { fmt.Println("Failed to set etcd value:", err) os.Exit(-1) } fmt.Printf("SetValue with string(\"Hello\") Response: %s\n", r) r, err = connection.GetValue("/junk/blob1", false, false) if err != nil { fmt.Println("Failed to get etcd value:", err) os.Exit(-1) } fmt.Printf("GetValue Response: %s\n", r) if r.Node.Value != "Hello" { fmt.Printf("FAILED: get should return 'Hello'\n") os.Exit(-1) } // Delete Key r, err = connection.DeleteKey("/junk/blob1") if err != nil { fmt.Println("Failed to delete etcd key:", err) os.Exit(-1) } fmt.Printf("DeleteKey Response: %s\n", r) // --------------------------------------------------------------------------------------------------- // Delete non-existant Key r, err = connection.DeleteKey("/junk/doesNotExist") if err == nil { fmt.Printf("Found no error deleting a missing etcd key: %s/%s\n", err, r) os.Exit(-1) } fmt.Printf("DeleteKey errored as expected deleting a missing key: %s\n", err) // --------------------------------------------------------------------------------------------------- // Set with a TTL r, err = connection.SetValue("/junk/blob3", "Hello", 2) if err != nil { fmt.Println("Failed to set etcd value:", err) os.Exit(-1) } fmt.Printf("SetValue with string(\"Hello\", TTL=1) Response: %s\n", r) // Verify it was set r, err = connection.GetValue("/junk/blob3", false, false) if err != nil { fmt.Println("Failed to get etcd value:", err) os.Exit(-1) } fmt.Printf("GetValue Response: %s\n", r) if r.Node.Value != "Hello" { fmt.Printf("FAILED: get should return 'Hello'\n") os.Exit(-1) } // wait for the TTL above to expire and verify it is gone fmt.Printf("Sleep 3 seconds ..... to wait for key to expire\n") time.Sleep(3 * time.Second) r, err = connection.GetValue("/junk/blob3", false, false) if err == nil { fmt.Println("Failed to NOT get expired etcd value:", err) os.Exit(-1) } fmt.Println("Received expected error GETting expired key (missing key)") // --------------------------------------------------------------------------------------------------- // Background function to make 4 changes that will be picked up by the // coming watchers that require at least 4 changes to avoid timeouts. go func(keyRoot string) { time.Sleep(1 * time.Second) for t := 0; t < 4; t++ { newVal := keyRoot + strconv.Itoa(t) fmt.Printf("SetValue background Value for watcher test: %s\n", newVal) // Set followed by a 'Get' to verify _, err := connection.SetValue(newVal, "miscSillyValue") if err != nil { fmt.Println("Failed to set etcd value:", err) os.Exit(-1) } time.Sleep(time.Second / 2) } }("/junk/foobarOne") // --------------------------------------------------------------------------------------------------- // Get a single event for the watched key (blocking call) (consumes one of the background events) // Use the bool channel to abort this query if needed. ctrl := make(chan bool) r, err = connection.Watcher(ctrl, "/", true) if err != nil { fmt.Println("Failed: ", err) } else { fmt.Printf("EtcdResponse: %s\n", r) } // --------------------------------------------------------------------------------------------------- // Non-blocking event stream. Shutdown via bool channel. Consumes 3 of the background events. // Create event stream from key on cmd line, recursive == true events := connection.EventStream(ctrl, "/", true) // Receive exactly three events for i := 0; i < 3; i++ { timer := time.NewTimer(time.Second * 3) select { case msg := <-events: if msg.GetError() != nil { fmt.Println("Event ERR:", msg.GetError()) // Shutdown the event stream and restart ... most likely out of sync or etcd is dead ctrl <- true events = connection.EventStream(ctrl, "/junk", true) } else { fmt.Println("Event: ", msg) } case <-timer.C: fmt.Println("TIMEOUT: FAILED TO RECEIVE WATCHER EVENT from etcd") os.Exit(-1) } } // Shutdown event stream ctrl <- true close(ctrl) // --------------------------------------------------------------------------------------------------- // Recursive Get r, err = connection.GetValue("/", true, false) if err != nil { fmt.Println("Failed recursive GET:", err) os.Exit(-1) } fmt.Printf("Recursive GET results:\n%s", r) // ------------------------------------------------------------------------------------------------------- // Background competing set/get calls c1 := make(chan bool) go setAndCheck(&connection, c1, "/junk/key1", "Hello", 4000, 100) c2 := make(chan bool) go setAndCheck(&connection, c2, "/junk/key2", "HelloAgain", 1000, 1000000) // Sync up after both have finished <-c1 <-c2 // ------------------------------------------------------------------------------------------------------- // Final cleanup ... must exist r, err = connection.DeleteDir("/junk", true) if err != nil { fmt.Println("Failed to delete directory:", err) os.Exit(-1) } fmt.Printf("Successfully cleaned up by Deleting directory: %s\n", r) }