Skip to main content

Spot Collections

There are some use cases that call for strong consistency across all regions. For example, a financial application might need to show users' account balances. When users make a deposit, they want to see the result of this deposit reflected immediately when they view their balance (otherwise they may fear their money has been lost!). There should never appear to be more or less money in aggregate in the bank than there really is.

When performing read operations, here you want to read the latest copy of your data in global order. It provides the ability to read the latest change to your data across rows, regions and continents.

note

Spot Collections are only available on Enterprise customer accounts.

Contact support@macrometa.com if you have any questions.

Pre-requisite

Let's assume your

  • Tenant name is nemo@nautilus.com and
  • User password is xxxxx.

SDK download

  pyC8 requires Python 3.5+. Python 3.6 or higher is recommended

To install pyC8, simply run

$ pip3 install pyC8

or, if you prefer to use conda:

conda install -c conda-forge pyC8

or pipenv:

pipenv install --pre pyC8

Once the installation process is finished, you can begin developing applications in Python.

Code Sample

""" This file is a demo for spot collections """
import pprint
from c8 import C8Client

# Variables Access
URL = "api-play.paas.macrometa.io"
API_KEY = "my API key" #Change this to my API key
API_KEY_ID = "my API key ID" #Change this to my API key ID
GEO_FABRIC = "_system"

# Variables - DB
collection_name = "accounts"
read_query_name = "read_query"
read_query = {"query": {"name": read_query_name, "value":
"FOR account IN accounts RETURN account"}}
accounts_keys = "FOR k IN accounts RETURN k._key"
spot_gf_name = "spot"
region_urls = [
"ap-northeast.paas.macrometa.io",
"eu-central.paas.macrometa.io",
"eu-west.paas.macrometa.io"
]

# Variables - Data
data = [
{"_key": "1", "firstname": "Peter", "lastname": "Parker", "City": "NewYork"},
{"_key": "2", "firstname": "Bruce", "lastname": "Wayne", "City": "Gotham"},
{"_key": "3", "firstname": "Clark", "lastname": "Kent", "City": "Manhatten"},
{"_key": "4", "firstname": "Ned", "lastname": "Stark", "City": "Winterfell"},
{"_key": "5", "firstname": "Tywin", "lastname": "Lannister", "City": "Kings Landing"}
]
pp = pprint.PrettyPrinter(indent=4)


# Step 1: Open connection to GDN. You will be routed to closest region.
print(f"1. CONNECT: federation: {URL}, user: {API_KEY}")
client = C8Client(protocol='https', host=URL, port=443, apikey = API_KEY, geofabric=GEO_FABRIC)

#print("The connection was successful:", client.get_collections())

# Step 1.5: Assign a spot region.
spot_region = client.tenant(apikey = API_KEY)
dcl = spot_region.dclist(detail=False)
fabric = spot_region.useFabric(GEO_FABRIC)

if fabric.has_fabric(spot_gf_name):
print("Fabric", spot_gf_name, "already exists.")
else:
fabric.create_fabric(spot_gf_name, dclist=dcl,spot_creation_type=
fabric.SPOT_CREATION_TYPES.SPOT_REGION, spot_dc='eu-west.paas.macrometa.io')
print("Fabric", spot_gf_name, "has been created successfully.")

client.set_database_access_level(API_KEY_ID, spot_gf_name, "rw")

#print(fabric.properties())
client = spot_region.useFabric(spot_gf_name)
#print(client.properties())

spot_region_status = client.properties().get("options", {}).get("spotDc")
if spot_region_status == "":
print("The fabric does not have a spot region registered.")
print("Please remove the fabric and create a new fabric with a spot region.")
print("Stopping program.")
exit()
else:
print("Spot region for the fabric", spot_gf_name, "is: ", spot_region_status)
print("Continuing...")


# Step 2: Create or assign a spot collection.
# getCollectionDetails
def isSpotCollection():
""" This function checks if the given collection already exists and if true,
returns the property 'isSpot' """
for coll in client.collections():
if coll["name"] == collection_name:
return coll["isSpot"]

print(f"2. CREATE_COLLECTION: region: {URL}, collection: {collection_name}")
if client.has_collection(collection_name):
if isSpotCollection():
print(collection_name, "is a spot collection.")
print("Continuing...")
collection = client.collection(collection_name)
else:
print(collection_name, "is not a spot collection")
print("Remove the collection and create a new one as a spot collection.")
print("Stopping program.")
exit()
else:
collection = client.create_collection(collection_name, spot_collection=True)
print(collection_name, "has been created successfully")


# Step 3: Insert data into collection.
#get_keys = client.execute_restql("accounts_keys")
print(f"3. INSERT_DATA: region: {URL}, collection: {collection_name}")
#collection.insert_many(data)
print("Data has been inserted successfully inserted (duplicating data was avoided).")



# Step 4: Create a new query worker or look for the existing one, then read data from the collection.
print(f"4. READ_DATA: region: {URL}, collection: {collection_name}")
all_saved_queries = client.get_all_restql()

query_exists = False
for i in all_saved_queries:
if i["name"] == read_query_name:
query_exists = True
break

if not query_exists:
client.save_restql(read_query)
print("The NEW query has been saved.")
else:
print("Query already exists.")


print(client.execute_restql(read_query_name))
#print(client.execute_query("FOR account IN accounts RETURN account"))


# Step 5: Read data from other regions.
for region_url in region_urls:
print(f"\n5. DATA_MOBILITY: Reading from region: {region_url}")
#clientx = C8Client(protocol='https', host=region_url, port=443, geofabric=
#spot_gf_name, apikey= API_KEY)
print(client.execute_restql(read_query_name))


# Step 6: Delete data.
print(f"6. DELETE_DATA: fabric: {spot_gf_name}, collection: {collection_name}")
try:
collection.truncate()
client.delete_collection(collection_name)
client = spot_region.useFabric(GEO_FABRIC)
client.delete_fabric(spot_gf_name)
print("Spot collection and fabric have been deleted successfully.")
except Exception as e:
print("There was an error while deleting the spot collection or fabric.")
print("Details:", e)