I’m generating Snowflake ID’s: Snowflake ID - Wikipedia and I need an integer 1-1023 identifying the node. In Gigalixir I could use the HOST_INDEX environment variable for this when starting a node, but for Fly I only found FLY_ALLOC_ID, which is a UUID. What can I do without resorting to some kind hashing of FLY_ALLOC_ID, is there an env var similar to HOST_INDEX?
FLY_ALLOC_ID is actually a hex, so you should be good if you just convert it to an int. Something like:
System.fetch_env("FLY_ALLOC_ID") |> Integer.parse(16)
Thanks @kurt, but as I said I don’t want to resort to hashing. Integer.parse will just convert the hex representation of the UUID into its representation in base 10, and then I would have to hash it. This means collisions when I have only 1023 possible values.
Oh, I missed a piece of this. The first segment of the alloc ID is unique. So this should work without hashing, I think:
System.fetch_env("FLY_ALLOC_ID") |> String.split("-") |> List.first |> Integer.parse(16)
The alloc id is the only thing in the environment you can really use to uniquely identify a VM.
Isn’t FLY_ALLOC_ID a UUID? If so, the first segment is not guaranteed to be unique. Besides, converting it to an integer would give 16^8 (4294967296) possible values, which again means collisions when hashing to a 10 bit values (1024 possible values).
The first segment on its own is not guaranteed to be unique, no. Internally we deal with the whole UUID to ensure uniqueness.
For users, the probability of the first segment colliding with another for the same app is very unlikely. Still, it is not a guarantee.
Our next iteration of instances IDs are short and guaranteed to be unique. Unfortunately that’s not ready yet.
HOST_INDEX represent the server on which your app is running or a unique index representing the instance of your app?
@jerome HOST_INDEX is a unique index representing the running instance.
From the Gigalixir docs:
HOST_INDEX contains the index of the replica. The hostname for each replica is randomly generated which can be a problem for services like DataDog and NewRelic who charge by the host. We also keep a sort of ordered list of your replicas that you can use to report hostnames to keep your number of hosts low. Each replica currently running will have a different HOST_INDEX, but once a replica is terminated, its HOST_INDEX can be re-used in another replica.
The only way I can really imagine getting reliable 0-1024 values is with DNS and a bunch of logic.
You can run the equivalent of
dig AAAA <app>.internal to get a list of all IPs. That will return them in age order (somewhat reliably, not a guaranty). You could map those to an autoincrementing integer in a database, or do something clever in memory. The IPs will change on deploy, though, so be aware of that.
Also, as an aside, we do enforce uniques of the first segment of the alloc ID while VMs are running. They’re not unique forever, but they’re unique at any given point in time.