Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1217)

Unified Diff: go/src/infra/gae/libs/gae/doc.go

Issue 1222983002: Add filters for RawDatastore (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@abstract
Patch Set: remove memory diff Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: go/src/infra/gae/libs/gae/doc.go
diff --git a/go/src/infra/gae/libs/gae/doc.go b/go/src/infra/gae/libs/gae/doc.go
index a42695bac5e402f1eeecd60667eb74c1051b4423..2704e4c15b83786e22c7f224e9696500b9e5f8b4 100644
--- a/go/src/infra/gae/libs/gae/doc.go
+++ b/go/src/infra/gae/libs/gae/doc.go
@@ -7,56 +7,81 @@
// APIs for testing (or potentially implement a different backend for them).
//
// gae currently provides interfaces for:
-// * Datastore
+// * RawDatastore (a less reflection-magic version of Datastore)
// * Memcache
// * TaskQueue
// * GlobalInfo (e.g. Namespace, AppID, etc.)
//
// A package which implements the gae is expected to provide the following:
-// * A package function `Enable(c context.Context, ...) context.Context`
+// * A package function `Use(c context.Context, ...) context.Context`
// This function is expected to add any information to c which is necessary
// for the rest of its implementations to work. This may be something like
// an `appengine.Context` or some connection information for an external
// server. The `...` in the function signature may be any additional data
-// needed.
-// * Any of the package functions:
-//
-// UseDS(context.Context) context.Context
-// UseMC(context.Context) context.Context
-// UseTQ(context.Context) context.Context
-// UseGI(context.Context) context.Context
-//
-// each of which would call gae.Set<service>Factory with the factory
-// function for that interface type.
-// * A `Use(context.Context) context.Context` function which calls all of the
-// `Use*` package functions implemented by the package.
-// * Partially-implemented interfaces should embed one of the Dummy* structs
-// which will panic with an appropriate error for unimplemented
-// methods.
-//
-// see "infra/gae/libs/gae/oldsdk" for an appengine-backed implementation.
-//
-// Datastore struct serialization uses the tag name 'gae' instead of 'datastore',
-// and uses gae.DSKey but otherwise behaves identically. You must use the
-// new-SDK primitive types (like GeoPoint, ByteString, etc.), even when using
-// the old-SDK implementation of the factories. This was done to ensure that all
-// code written against gae is go-gettable, and was deemed as less-annoying than
-// re-defining all of the types identically.
-//
-// Kinds/Keys work similarly to how they work in goon (except you no longer use
-// the goon + datastore tags and key/control-related tags start with $):
-//
-// type FooModel struct {
-// _kind string `gae:"$kind,Foo"`
-// Id string `gae:"$id"`
-// Parent DSKey `gae:"$parent"`
-//
-// privateSkipped bool
-// AutoSave int
-// NoSaveField string `gae:"-"`
-// NoIndexField float `gae:",noindex"`
-// DiffName string `gae:"coolName"`
+// needed (or it may be empty).
+//
+// * Partially-implemented interfaces should embed one of the dummy
+// implementations in the `dummy` subpackage which will panic with
+// an appropriate error for unimplemented methods.
+//
+// see "infra/gae/libs/gae/prod" for an appengine-backed implementation.
+// see "infra/gae/libs/gae/memory" for an in-memory implementation.
+//
+// You will typically access one of the service interfaces in your code like:
+// // This is the 'production' code
+// func HTTPHandler(r *http.Request) {
+// c := prod.Use(appengine.NewContext(r))
+// CoolFunc(c)
+// }
+//
+// // This is the 'testing' code
+// func TestCoolFunc(t *testing.T) {
+// c := memory.Use(context.Background())
+// CoolFunc(c)
+// }
+//
+// func CoolFunc(c context.Context, ...) {
+// rds := gae.GetRDS(c) // returns a RawDatastore object
+// mc := gae.GetMC(c) // returns a Memcache object
+// // use them here
+//
+// // don't pass rds/mc/etc. directly, pass the context instead.
+// SomeOtherFunction(c, ...)
+//
+// // because you might need to:
+// rds.RunInTransaction(func (c context.Context) error {
+// SomeOtherFunction(c, ...) // c contains transaction versions of everything
+// }, nil)
+// }
+//
+// RawDatastore struct serialization is provided by the `helper` subpackage. All
+// supported struct types and interfaces are provided in this package, however.
+// You can operate without any struct serizialization/reflection by exclusively
+// using DSPropertyMap. A goon-style Datastore interface is also provided in the
+// `helper` subpackage.
+//
+// Each service also supports "filters". Filters are proxy objects which have
+// the same interface as the service they're filtering, and pass data through to
+// the previous filter in the stack. Conceptually, a filtered version of, for
+// example, the RawDatastore, could look like:
+// User
+// <mcache filter (attempts to use memcache as a cache for datastore)>
+// <count filter (keeps a conter for how many times each API is used)>
+// Memory RawDatastore (contains actual data)
+//
+// So GetRDS would return the full stack, and GetRDSUnfiltered would only
+// return the bottom layer. In code, this would look like:
+// func HTTPHandler(r *http.Request) {
+// c := prod.Use(appengine.NewContext(r)) // production datastore
+// c, rawCount := count.FilterRDS() // add count filter
+// c = mcache.FilterRDS(c) // add mcache filter
+// c, userCount := count.FilterRDS() // add another count filter
// }
//
-// func (FooModel) GetCachePolicy() DSCacheFlags { return DSCache }
+// Filters may or may not have state, it's up to the filter itself. In the case
+// of the count filter, it returns its state from the Filter<Service> method,
+// and the state can be observed to see how many times each API was invoked.
+// Since filters stack, we can compare counts from rawCount versus userCount to
+// see how many calls to the actual real datastore went through, v. how many
+// went to memcache, for example.
package gae

Powered by Google App Engine
This is Rietveld 408576698