Skip to content

Instantly share code, notes, and snippets.

@fostergn
Last active January 24, 2023 08:03
Show Gist options
  • Save fostergn/bebc87e1dc4a5df025b8d9b09ecaa62f to your computer and use it in GitHub Desktop.
Save fostergn/bebc87e1dc4a5df025b8d9b09ecaa62f to your computer and use it in GitHub Desktop.
const crypto = require("crypto");
/**
* deterministicPartitionKey() returns a deterministic partition key for a given event.
* @param {object} event
* @returns {string} partition key
*
**/
exports.deterministicPartitionKey = (event) => {
const TRIVIAL_PARTITION_KEY = "0";
const MAX_PARTITION_KEY_LENGTH = 256;
if (!event) return TRIVIAL_PARTITION_KEY
if (event.partitionKey && typeof event.partitionKey !== "string") {
return JSON.stringify(event.partitionKey);
}
if (event.partitionKey && event.partitionKey?.length < MAX_PARTITION_KEY_LENGTH) {
return event.partitionKey;
}
const data = JSON.stringify(event);
return crypto.createHash("sha3-512").update(data).digest("hex");
};
/**
* Explanation:
*
* I optimized for de-nesting and using conditionals to inverse the control flow (keep
* main function logic outside of conditional statements
*
* The goal is that the function starts to reflect our test cases: edge cases get handled and returned early.
* The result should be that we clearly understand what are the edge cases we are handling, and what is the main case
* that this function is written for. Some of our conditions don't feel all that DRY in this state, but :shrug: the alternative
* would mean that the order of conditions affects the logic which is less than ideal.
*
* Another weak point with this code (which isn't fixed here) is that the surface area is large: we accept an object, integer, string etc. This
* might be by design for a very flexible function, but typically in an organization's API this isn't by design.
**/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment