Quickstart | Configure the Etcd server | Using Etcd Client
A Julia Etcd client implementation.
julia> Pkg.add("Etcd")
julia> using EtcdThe library defaults to Etcd server at 127.0.0.1:4001.
server = Etcd.EtcdServer()
EtcdServer("127.0.0.1",4001,"v2")Or you can specify the server ip address and port number.
server = Etcd.EtcdServer("172.17.42.1",5001)
EtcdServer("172.17.42.1",5001,"v2")etcd = Etcd.EtcdServer()
EtcdServer("127.0.0.1",4001,"v2")Set a value on the /foo/bar key:
julia> Etcd.set(etcd,"/foo/bar","Hello World")
["action"=>"set","node"=>["createdIndex"=>1803,"key"=>"/foo/bar","value"=>"Hello World","modifiedIndex"=>1803]]Set a value on the /foo/bar key with a value that expires in 60 seconds:
julia> Etcd.set(etcd,"/foo/bar","Hello World",ttl=60)
["action"=>"set","node"=>["createdIndex"=>1805,"key"=>"/foo/bar","value"=>"Hello World","expiration"=>"2014-03-25T01:19:39.182867998Z","ttl"=>60,"modifiedIndex"=>1805]]Note that the ttl value can be set with all the following commands by specifying ttl=ttl_expiry_time_in_seconds
Conditionally set a value on /foo/bar if the previous value was "Hello world". test_and_set is an alias for compare_and_swap.
julia> Etcd.compare_and_swap(etcd,"/foo/bar","Goodbye Cruel World",prev_value="Hello World")
["action"=>"compareAndSwap","prevNode"=>["createdIndex"=>1811,"key"=>"/foo/bar","value"=>"Hello World","modifiedIndex"=>1811],"node"=>["createdIndex"=>1811,"key"=>"/foo/bar","value"=>"Goodbye Cruel World","modifiedIndex"=>1812]]You can also conditionally set a value based on the previous etcd index.
Conditionally set a value on /foo/bar if the previous etcd index was 1818:
julia> Etcd.compare_and_swap(etcd,"/foo/bar","Goodbye Cruel World",prev_index=1818)
["action"=>"compareAndSwap","prevNode"=>["createdIndex"=>1818,"key"=>"/foo/bar","value"=>"Hello World","modifiedIndex"=>1818],"node"=>["createdIndex"=>1818,"key"=>"/foo/bar","value"=>"Goodbye Cruel World","modifiedIndex"=>1820]]Create a new key /foo/boo, only if the key did not previously exist:
julia> Etcd.create(etcd,"/foo/boo","Hello World")
["action"=>"create","node"=>["createdIndex"=>1822,"key"=>"/foo/boo","value"=>"Hello World","modifiedIndex"=>1822]]Create a new dir /fooDir, only if the directory did not previously exist:
julia> Etcd.create_dir(etcd,"/fooDir")
["action"=>"create","node"=>["createdIndex"=>1826,"key"=>"/fooDir","dir"=>true,"modifiedIndex"=>1826]]Update an existing key /foo/bar, only if the key already existed:
julia> Etcd.update(etcd,"/foo/boo","Merhaba")
["action"=>"update","prevNode"=>["createdIndex"=>1822,"key"=>"/foo/boo","value"=>"Hello World","modifiedIndex"=>1822],"node"=>["createdIndex"=>1822,"key"=>"/foo/boo","value"=>"Merhaba","modifiedIndex"=>1828]]You can also Create (create_dir) or update (update_dir) a directory.
Get the current value for a single key in the local etcd node:
julia> Etcd.get(etcd,"/foo/bar")
["action"=>"get","node"=>["createdIndex"=>1817,"key"=>"/foo/bar","value"=>"Hello World","modifiedIndex"=>1817]]Add recursive=true to recursively list sub-directories.
Check for existence of a key:
julia> Etcd.exists(etcd,"/foo/bar")
trueDelete a key:
julia> Etcd.create_dir(etcd,"/foo/qux")
julia> Etcd.delete(etcd,"/foo/boo")
["action"=>"delete","prevNode"=>["createdIndex"=>1822,"key"=>"/foo/boo","value"=>"Merhaba","modifiedIndex"=>1828],"node"=>["createdIndex"=>1822,"key"=>"/foo/boo","modifiedIndex"=>1837]]Delete an empty directory:
julia> Etcd.delete_dir(etcd,"/foo/qux")
["action"=>"delete","prevNode"=>["createdIndex"=>1838,"key"=>"/foo/qux","dir"=>true,"modifiedIndex"=>1838],"node"=>["createdIndex"=>1838,"key"=>"/foo/qux","dir"=>true,"modifiedIndex"=>1839]] Recursively delete a key and all child keys:
julia> Etcd.get(etcd,"/foo",recursive=true)
["action"=>"get","node"=>["nodes"=>{["createdIndex"=>1817,"key"=>"/foo/bar","value"=>"Hello World","modifiedIndex"=>1817],["createdIndex"=>1818,"key"=>"/foo/baz","value"=>"Goodbye Cruel World","modifiedIndex"=>1820]},"createdIndex"=>1803,"key"=>"/foo","dir"=>true,"modifiedIndex"=>1803]]
ulia> Etcd.delete_dir(etcd,"/foo",recursive=true)
["action"=>"delete","prevNode"=>["createdIndex"=>1803,"key"=>"/foo","dir"=>true,"modifiedIndex"=>1803],"node"=>["createdIndex"=>1803,"key"=>"/foo","dir"=>true,"modifiedIndex"=>1844]]
julia> Etcd.get(etcd,"/foo",recursive=true)
["message"=>"Key not found","cause"=>"/foo","index"=>1844,"errorCode"=>100]Conditionally delete /foo/bar if the previous value was "Hello world":
julia> Etcd.create(etcd,"/foo/bar","bar value")
["action"=>"create","node"=>["createdIndex"=>1845,"key"=>"/foo/bar","value"=>"bar value","modifiedIndex"=>1845]]
julia> Etcd.compare_and_delete(etcd,"/foo/bar",prev_value="bar value")
["action"=>"compareAndDelete","prevNode"=>["createdIndex"=>1845,"key"=>"/foo/bar","value"=>"bar value","modifiedIndex"=>1845],"node"=>["createdIndex"=>1845,"key"=>"/foo/bar","modifiedIndex"=>1846]]Conditionally delete /foo/bar if the previous etcd index was 1849:
julia> Etcd.create(etl,"/foo/bar","Hello World")
["action"=>"create","node"=>["createdIndex"=>1849,"key"=>"/foo/bar","value"=>"Hello World","modifiedIndex"=>1849]]
julia> Etcd.compare_and_delete(etl,"/foo/bar",prev_index=1849)
["action"=>"compareAndDelete","prevNode"=>["createdIndex"=>1849,"key"=>"/foo/bar","value"=>"Hello World","modifiedIndex"=>1849],"node"=>["createdIndex"=>1849,"key"=>"/foo/bar","modifiedIndex"=>1850]]Watch for only the next change on a key:
julia> Etcd.watch(etcd,"/foo/bar",ev->println("I'm watching you:",ev))
Task (queued) @0x00000000024b65f0
...
... next make some modification to "/foo/bar" key and the callback is then called:
...
I'm watching you:["action"=>"update","prevNode"=>["createdIndex"=>1851,"key"=>"/foo/bar","value"=>"Hello World","modifiedIndex"=>1851],"node"=>["createdIndex"=>1851,"key"=>"/foo/bar","value"=>"Who's watching the watchers","modifiedIndex"=>1852]]You can also specify the following options:
recursive=trueto watch the key and all it's children.wait_indexto watch starting with the provided index.
Continuously watch a key:
julia> Etcd.keep_watching(etcd,"/foo/bar",ev->println("I'll keep on watching you:",ev))
.... The callback will keep getting called for every change to the keyWatch conditionally, while passing a function which will terminate the watch when it evaluates to true, for example:
julia> Etcd.watch_until(etcd,"/foo",ev->println("I'll be watching you (only 3 times):",ev),begin let l = 0; ev->begin l += 1; if l > 2 true else false end end end end,recursive=true)julia> Etcd.machines(etcd)
"http://172.17.42.1:5001, http://172.17.42.1:5002, http://172.17.42.1:5003"You can retrieve Etcd stats by specifying one of store, self or leader.
For example to get the store stats:
julia> Etcd.stats(etcd,"store")
["getsSuccess"=>193,"updateFail"=>88,"watchers"=>1,"setsSuccess"=>710,"setsFail"=>2869,"expireCount"=>460,"compareAndSwapSuccess"=>3,"getsFail"=>10,"deleteSuccess"=>8,"createFail"=>10,"createSuccess"=>25,"compareAndDeleteSuccess"=>3,"deleteFail"=>3,"compareAndSwapFail"=>1,"updateSuccess"=>386,"compareAndDeleteFail"=>0]Set a leader for the cluster (notice the leading slash is omitted) by specifying a name and a ttl as follows:
julia> Etcd.set_leader(etcd,"my-cluster",name="leader-1",ttl=60)
"1853"Get the leader of the cluster:
julia> Etcd.get_leader(etcd,"my-cluster")
"leader-1"Deleting the leader:
julia> Etcd.delete_leader(etcd,"my-cluster",name="leader-1")
""The lock module can be used to provide a distributed lock for resources among multiple clients. Only one client can have access to the lock at a time, once the lock holder releases the lock the next client waiting for the lock can acquire it.
lock_retrieve gets the lock index of the lock. lock_acquire is used to acquire the lock and it will return the lock index.
... another client acquires the lock
$ curl -L http://127.0.0.1:4001/mod/v2/lock/mylock -XPOST -d ttl=100
1876
julia> Etcd.lock_retrieve(etcd,"mylock")
"1876"
julia> Etcd.lock_acquire(etcd,"mylock",ttl=100)
... blocks until ttl for lock expires or until lock is released ...
"1878"You can also renew the lock:
julia> Etcd.lock_renew(etcd,"mylock",index=1885,ttl=60)And release the lock:
julia> Etcd.lock_release(etcd,"mylock",index=1890)