Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
# containers
cf.containers.create("new_container", metadata: { "you're on your own here bud": "because you wanted all of the power" }) # Should we even offer metadata mutation at create time????
container = cf.containers["my-test-dir"]
# metadata (Hash-like protocol)
container.metadata # Return a Hash of the metadata less the X-Container-Meta- prefixes
container.metadata["price"] = "4.20"
.readers=(*args) # Set list of users with container read privileges
.writers=(*args) # Set list of users with container read privileges
.enable_versioning(versions_container = "versions")
.disable_versioning # TODO: Try "X-Remove-Versions-Location" first to see if we support it and then get back to Anne
container.sync_to(remote_container_path, with_key: key)
container.disable_sync # Have to remove the sync key per
# files
container.all # up to 10_000
.all(limit: 100) # with optional limit
.find_by_name("foo", limit:100)
.find_by_name_beginning_with("foo") # using the "prefix" feature

This comment has been minimized.

Copy link

@smashwilson smashwilson commented Jul 15, 2014

Random comments and 💭s :

  • Returning a "Hash-like" object for container.metadata feels like trouble to me. I'd rather have an extra method call to get a real, honest Hash explicitly with to_h than try to fake it like fog does with Array for its collections. To be clear, I'm fine with implementing #[] and #[]= but I feel like we should avoid attempting to be more "Hash-like" than that - we shouldn't support enumeration, etc. (Maybe this is what you already meant; just want to be sure.)
  • What are the timing semantics for metadata manipulation? Do accesses and deletions take effect immediately, or should there be a analog? I tend to fall on the side of having some way to persist changes explicitly so that operations can be batched.
  • I hadn't actually heard about sync before. What does it do, just keep two containers in sync... ?
  • find_by_name_beginning_with is awkward. find_by_name_prefix?
  • We're using a fog-like cf.containers "collection" at the top level, but files are enumerated directly from the container with .all or .find_.*. I'd say pick one or the other for consistency: either "collection objects (preferably not "fake Arrays", see above) or "flat access":
# "Collection" objects
everything = cf.containers.list
some = cf.containers.list(page: 3, per_page: 300)
container = cf.containers['specific-one']

container.files.list(prefix: 'foo')

# OR

# list methods
everything = cf.list_containers
some = cf.list_containers(page: 3, per_page: 300)
container = cf.container_named('specific_one')

container.list_files(prefix: 'foo')

I'm not sure which style I actually prefer - the former keeps API operations nicely organized by topic, while the latter is simpler and keeps the SDK more flat, which is easier to navigate.


This comment has been minimized.

Copy link
Owner Author

@elight elight commented Jul 16, 2014

  • {page: X, per_page: Y} doesn't work with our API because distributed system where CAP can result in inconsistencies in pagination. It's why OpenStack is using a "limit-marker" approach instead. I'm trying to hide those semantics (because I feel they deviate too much from the Rails/web dev world too much) by hiding the marker and letting the user specify a limit.
  • When I said Hash-like, I meant insofar as providing [] and []=(arg) methods and not necessarily making it Enumerable. Granted if being Enumerable is easy, I'd tend to go for it because idiomatic Ruby.
  • RE: batching operations, the question is where to draw the line. There are a lot of orthogonal pieces of metadata that are all updatable via the same API call. But they're orthogonal. Grouping them together in a single API call could make the SDK less clear.
  • I had initially considered the "list methods" approach, as you described it but I could see it leading to an explosion of methods on the CloudFiles class. I was hesitant to introduce the Containers class. I'm still considering axing it and pulling its behavior back into the CloudFiles class. My concern is that I can see CloudFiles becoming too cluttered already. I prematurely (my emphasis) extracted Containers as just a logical grouping for behaviors related to containers; it doesn't have any state of its own. So there's another SDK option:
file = cf["container-name"]["file-name"]

... but that starts to feel more like PERL or really bad Ruby as it its unclear to the reader what the first and second calls to [] are doing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment