def testUpdate(self): print(tc.uri(Right).port()) assert tc.uri(Right).port() == 8703 left = start_host("test_multi_host_left", [Left]) right = start_host("test_multi_host_right", [Right]) left.put("/app/balance/weigh", None, 5) print_lines(5) self.assertEqual(left.get("/app/balance/weight"), 5) self.assertEqual(right.get("/app/balance/weight"), 15)
class Right(Balance): __uri__ = tc.uri(Balance) + "/right" @tc.put_method def weigh(self, txn, key: tc.Nil, weight: tc.Number): left = tc.use(Left) txn.total = CONSERVED txn.update = tc.After(left.weigh(None, txn.total - weight), self.weight.set(weight)) return tc.If(self.weight.subject() == weight, None, txn.update)
def testWorkflow(self): host = start_host("test_yc_demo", [Producer, Wholesaler]) actual = host.get("/app/producer/inventory") self.assertEqual(IN_STOCK, actual) with self.assertRaises(tc.error.Unauthorized): host.post("/app/wholesaler/buy", {"quantity": 10}) host.put("/app/producer/install", "http://127.0.0.1:8702" + tc.uri(Wholesaler), ["buy"]) host.post("/app/wholesaler/buy", {"quantity": 10}) self.assertEqual(90, host.get("/app/producer/inventory"))
class Right(Balance): __uri__ = tc.uri(Balance) + "/right" @tc.put_method def weigh(self, txn, key: tc.Nil, new_value: tc.Number): left = tc.use(Left) txn.total = CONSERVED txn.current = self.weight.subject() txn.update = tc.After(self.weight.set(new_value), left.weigh(None, txn.total - new_value)) return tc.If(txn.current == new_value, None, txn.update)
def start_host(name, clusters=[], overwrite=True): port = PORT if clusters: port = tc.uri(clusters[0]).port() port = port if port else PORT config = [] for cluster in clusters: cluster_config = f"config/{name}" cluster_uri = tc.uri(cluster) if cluster_uri.port() is not None and cluster_uri.port() != port: raise ValueError( f"invalid port {cluster_uri.port()}, expected {port}") if cluster_uri.host(): cluster_config += f"/{cluster_uri.host()}" if cluster_uri.port(): cluster_config += f"/{cluster_uri.port()}" cluster_config += str(cluster_uri.path()) tc.write_cluster(cluster, cluster_config, overwrite) config.append(cluster_config) data_dir = "/tmp/tc/tmp/" + name if overwrite and os.path.exists(data_dir): shutil.rmtree(data_dir) print(f"start host on port {port}") return tc.host.Local(TC_PATH, workspace="/tmp/tc/tmp/" + name, data_dir=data_dir, clusters=config, port=port, log_level="debug", force_create=True)
class Left(Balance): __uri__ = "http://127.0.0.1:8702" + tc.uri(Balance) @tc.put_method def weigh(self, txn, key: tc.Nil, new_value: tc.Number): right = tc.use(Right) txn.total = CONSERVED txn.current = self.weight.subject() txn.update = tc.After( self.weight.set(new_value), right.weigh(None, txn.total - new_value)) return tc.If(txn.current == new_value, None, txn.update)