Partition Keys in Longevity

I'm so excited to announce the release of longevity version 0.16.0! Longevity now supports partition keys - a key where, given a key value, we can determine the node in a distributed database where the data resides (or would reside, if it existed). This is a critical feature for NoSQL databases in a distributed context. A partition key is implemented with sharding in MongoDB, and with partitioning in Cassandra.

I'll provide a brief example of a partition key here after the jump, but to learn more about it, please take a look at the user manual.

Suppose you are persisting users, and you want your user data to be partitioned by username. Here's how it would look:

import longevity.subdomain.KeyVal
import longevity.subdomain.Persistent
import longevity.subdomain.PType

case class Username(username: String) extends KeyVal[User, Username]

case class User(
  username: Username,
  firstName: String,
  lastName: String)
extends Persistent

object User extends PType[User] {
  object props {
    val username = prop[Username]("username")
  object keys {
    val username = partitionKey(props.username)  
Pretty simple huh?

Partition keys was the last longevity feature that I've felt was essential to get into a 1.0 release. Because I am fully committed to semantic versioning, I have a new set of features at the top of list now: Features that are both important, and are known or suspected to break backwards compatibility. These are some really neat and exciting features that will make longevity more powerful and easier for you to use:
  • Persist Custom Types: Currently, all the types you want to persist need to be case classes with a single parameter list. I plan to enhance things so that you can persist any types you want. Roughly speaking, all you would need to do would be to supply apply and unapply methods similar to those that are generated for you for case classes. This would allow you to persist classes that were not case classes, including types provided by third-party libraries.
    • One off-shoot to this feature is that I will end up removing the need to have your classes extend empty traits, like the case class User ... extends Persistent above. I think most users will like that. I'm thinking I will remove the Persistent and related traits entirely. What do you think?
  • Macro for Persistent Properties: Currently, all the properties you use in your keys, indexes and queries need to be manually defined by the user. For each one, you have to specify both the type and the property path. I'm planning to write a macro that will generate the complete set of properties for you. This will take some effort, and I'm not 100% sure at this point that it's going to fly, but I think it will work.
  • Classpath Scanning for Subdomain: Currently, the user has to re-enumerate all the types they want to persist when building the subdomain. I plan on writing a classpath scanning routine that will collect them all for you, saving you some busy work, and avoiding bugs involved with failing to keep the list up to date.
So what do you think, which of these features would you like to see first? I plan to tackle them in the order presented here. What other features or changes would you like to see? Please chime in. You can comment here, on the user forum, or send me a tweet. I need more feedback from you in order to steer this project in the best direction!!

Thanks so much for reading and using longevity!

No comments:

Post a Comment