You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
DISCUSSION: abstractions of service calls in storage #545
Generally speaking, the library functions seem to abstract when service interactions occur from the user. In other words, some operations are local to the object (e.g acl.grant), others interact with the service (e.g. acl.save), while still others interact only some of the time (e.g. bucket.default_object_acl).
If you're going to follow this model (and I'm not sure you should), I think you need to add preconditions to most service calls to ensure that confusing things don't happen.
A good example of this would be the save and reload functions in the ACL class. When should the user call reload()? I don't think it's clear. What happens when the user calls save() but the target ACL has changed on the service side since we last loaded it?
This abstraction is especially dangerous because it works very well when a single client is involved but creates subtle problems when deployed at scale.
In addition to a more focused / consistent approach, I think the methods in Connection should have no side effects, just as we do in the datastore subpackage.
Just look at something like Connection.delete_bucket. When called with force=True it makes an arbitrary (potentially large) number of delete calls for individual objects. This abstraction should happen on the Bucket class (if at all), not on the Connection. (has been done)
Some other differences / poorly aligned overlap (as of 86acc4a):
Connection.make_request in storage vs. Connection._request in datastore (big overlap) (_make_request is now protected)
Connection.api_request in storage vs. Connection._rpc in datastore (public vs. private) (api_request is used a lot elsewhere, so SHOULD be public)
Connection.__iter__ loops through all buckets (seems out of place). This is used in get_all_buckets. (has been removed)
Connection.lookup does what Connection.get_bucket (probably) should do. Either way, they are too similar and one should be removed. (has been removed)
Connection.new_bucket factory should be scrapped and higher quality Bucket constructor implemented (if needed) (ditto on Bucket.from_dict, a classmethod which could be incorporated into the constructor) (has been done)
Connection.generate_signed_url does not actually make any HTTP request and only relies on the associated credentials object for the connect. Consider making a function? (has been done)
Connection.__contains__ feels out of place and is a proxy for "does connection have access to this bucket? / does this bucket exist?" ((has been removed)
In addition, there are 10 uses of Connection.api_request outside of the Connection class:
@thobrla We are trying to distill your concerns further. /cc @tseaver
RE: "others interact only some of the time": this is done mostly for lazy loading, which is a benefit for users. Do you think this is problematic?
RE: "ACL.save() without an ACL.reload()" I've been trying to unravel service calls and but having a hard time keeping track due to the convenience mapping of metadata keys to native Python properties. We have been discussing a bit, but don't have a clear solution / path forward.
Activity
dhermes commentedon Jan 23, 2015
In addition to a more focused / consistent approach, I think the methods in
Connectionshould have no side effects, just as we do in thedatastoresubpackage.Just look at something like(has been done)Connection.delete_bucket. When called withforce=Trueit makes an arbitrary (potentially large) number of delete calls for individual objects. This abstraction should happen on theBucketclass (if at all), not on theConnection.Some other differences / poorly aligned overlap (as of 86acc4a):
(Connection.make_requestinstoragevs.Connection._requestindatastore(big overlap)_make_requestis now protected)(Connection.api_requestinstoragevs.Connection._rpcindatastore(public vs. private)api_requestis used a lot elsewhere, so SHOULD be public)(has been removed)Connection.__iter__loops through all buckets (seems out of place). This is used inget_all_buckets.(has been removed)Connection.lookupdoes whatConnection.get_bucket(probably) should do. Either way, they are too similar and one should be removed.(has been done)Connection.new_bucketfactory should be scrapped and higher qualityBucketconstructor implemented (if needed) (ditto onBucket.from_dict, aclassmethodwhich could be incorporated into the constructor)(has been done)Connection.generate_signed_urldoes not actually make any HTTP request and only relies on the associatedcredentialsobject for the connect. Consider making a function?((has been removed)Connection.__contains__feels out of place and is a proxy for "does connection have access to this bucket? / does this bucket exist?"In addition, there are 10 uses of
Connection.api_requestoutside of theConnectionclass:These should be consolidated inside
Connectionitself. (Ditto for the 2 uses ofbuild_api_urlinstorage.key.)Folding Blob.from_dict and Bucket.from_dict into constructors.
Folding Blob.from_dict and Bucket.from_dict into constructors.
dhermes commentedon Feb 10, 2015
@thobrla We are trying to distill your concerns further. /cc @tseaver
RE: "others interact only some of the time": this is done mostly for lazy loading, which is a benefit for users. Do you think this is problematic?
RE: "
ACL.save()without anACL.reload()" I've been trying to unravel service calls and but having a hard time keeping track due to the convenience mapping of metadata keys to native Python properties. We have been discussing a bit, but don't have a clear solution / path forward.Are you aware of
thobrla commentedon Feb 10, 2015
It is a benefit for users until an error occurs (even a transient service error) and breaks the illusion of atomicity.
Batching configuration changes into a single patch request is fine.
dhermes commentedon Feb 13, 2015
Closing based on @thobrla comment.
docs: updated some method comments and added an explicit note that De…
build(deps): [autoapprove] bump cryptography from 41.0.0 to 41.0.2 (#545
fix: Add async context manager return types (#545)
build(deps): [autoapprove] bump pygments from 2.13.0 to 2.15.0 (#545)
chore(deps): update dependency ipython to v8.8.0 (#545)
chore(deps): update dependency ipython to v8.8.0 (#545)
chore(python): use black==22.3.0 (#545)
feat: add iam methods to templates (#545)
chore: update docfx minimum Python version (#545)
chore(deps): update actions/download-artifact action to v3 (#545)
chore: release 1.6.1 (#545)
chore: release 2.11.0 (#545)
fix: DatabaseWrapper method impl and potential bugfix (#545)
docs: cleanup the transaction section of README a bit (#545)
docs: pass explicit 'client' in '{Blob.Bucket}.from_string' examples (#…
chore: release 1.42.1 (#549)
chore(python): disable dependency dashboard (#545)