Commit fb620301 authored by Levin Zimmermann's avatar Levin Zimmermann Committed by Kirill Smelkov

lib/zodb/zstor_2zurl/NEO: support > 1 master nodes

The old code raised an explicit exception when converting a NEO storage
with > 1 master nodes into a URI. Perhaps the rationale for this exception
was that there isn't any agreed on order of master nodes in a NEO URI,
which means that building a URI from such a storage could potentially
break the invariant that any client which points to the same storage
should result in the same WCFS mountpoint.
With levin.zimmermann/wendelin.core@6f5196fa we can now rely on
WCFS mountpoint calculation to always return the same mountpoint even if
the order of master node addresses differ. Therefore we can drop this
exception and allow WCFS to support NEO clusters with more than one master.

--------

kirr: support for multiple masters was simply not implemented because in
a05db040 (lib/zodb: Teach zstor_2zurl about ZEO, NEO and Demo storages)
I though that we do not yet actually need it and wanted to have
something minimal first.

I agree that in WCFS context it is ok and makes sense to normalize zurl
to have masters coming in particular order. But at zstor_2zurl level we
rely on the order of masters that app.nm.getMasterList gives us. The
normalization is separate function.

/reviewed-by @kirr
/reviewed-on !17
parent 63153845
......@@ -514,19 +514,20 @@ def test_zstor_2zurl(tmpdir, neo_ssl_dict):
sslp = ";".join(("%s=%s" % (q(k), q(v)) for k, v in sorted(neo_ssl_dict.items())))
_ = assert_zurl_is_correct
_(fs1("test.fs"), "file://%s/test.fs" % tmpdir) # FileStorage
_(zeo("1", "/path/to/zeo.sock"), "zeo:///path/to/zeo.sock") # ZEO/unix
_(zeo("test", "/path/to/zeo.sock"), "zeo:///path/to/zeo.sock?storage=test") # + non-default storage name
_(zeo("1", ("127.0.0.1", 1234)), "zeo://127.0.0.1:1234") # ZEO/ip4
_(zeo("test", ("127.0.0.1", 1234)), "zeo://127.0.0.1:1234?storage=test") # + non-default storage name
_(zeo("1", ("::1", 1234)), "zeo://[::1]:1234") # ZEO/ip6
_(zeo("test", ("::1", 1234)), "zeo://[::1]:1234?storage=test") # + non-default storage name
_(neo("test", "127.0.0.1:1234"), "neo://127.0.0.1:1234/test") # NEO/ip4
_(neo("test", "127.0.0.1:1234", 1), "neos://%s@127.0.0.1:1234/test" % sslp) # + ssl
_(neo("test", "[::1]:1234"), "neo://[::1]:1234/test") # NEO/ip6
_(neo("test", "[::1]:1234", 1), "neos://%s@[::1]:1234/test" % sslp) # + ssl
_(demo(zeo("base", ("1.2.3.4", 5)), # DemoStorage
fs1("delta.fs")), "demo:(zeo://1.2.3.4:5?storage=base)/(file://%s/delta.fs)" % tmpdir)
_(fs1("test.fs"), "file://%s/test.fs" % tmpdir) # FileStorage
_(zeo("1", "/path/to/zeo.sock"), "zeo:///path/to/zeo.sock") # ZEO/unix
_(zeo("test", "/path/to/zeo.sock"), "zeo:///path/to/zeo.sock?storage=test") # + non-default storage name
_(zeo("1", ("127.0.0.1", 1234)), "zeo://127.0.0.1:1234") # ZEO/ip4
_(zeo("test", ("127.0.0.1", 1234)), "zeo://127.0.0.1:1234?storage=test") # + non-default storage name
_(zeo("1", ("::1", 1234)), "zeo://[::1]:1234") # ZEO/ip6
_(zeo("test", ("::1", 1234)), "zeo://[::1]:1234?storage=test") # + non-default storage name
_(neo("test", "127.0.0.1:1234"), "neo://127.0.0.1:1234/test") # NEO/ip4
_(neo("test", "127.0.0.1:1234", 1), "neos://%s@127.0.0.1:1234/test" % sslp) # + ssl
_(neo("test", "[::1]:1234"), "neo://[::1]:1234/test") # NEO/ip6
_(neo("test", "[::1]:1234", 1), "neos://%s@[::1]:1234/test" % sslp) # + ssl
_(neo("test", "[::1]:1234\n[::2]:1234"), "neo://[::1]:1234,[::2]:1234/test") # + 2 master nodes
_(demo(zeo("base", ("1.2.3.4", 5)), # DemoStorage
fs1("delta.fs")), "demo:(zeo://1.2.3.4:5?storage=base)/(file://%s/delta.fs)" % tmpdir)
# Test exceptions
# invalid storage
......
......@@ -401,15 +401,17 @@ def zstor_2zurl(zstor):
masterv = app.nm.getMasterList()
if len(masterv) == 0:
raise RuntimeError("%r has empty master list" % zstor)
if len(masterv) > 1:
raise NotImplementedError("NEO client has multiple configured masters: %r" % (masterv,))
master = masterv[0]
host, port = master.getAddress()
if _is_ipv6(host):
host = "[%s]" % host
master_list = []
for master in masterv:
host, port = master.getAddress()
u += "%s:%s" % (host, port)
if _is_ipv6(host):
host = "[%s]" % host
master_list.append("%s:%s" % (host, port))
u += ",".join(master_list)
u += "/%s" % app.name
return u
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment