Store an object in memcache of GAE in Go - google-app-engine

I want to store an object in GAE's memcache using Go. The gae documentation only shows how to store a []byte here: https://developers.google.com/appengine/docs/go/memcache/overview
Of course there are general ways to serialize an object into []byte, by which my task could be accomplished. But by reading the memcache reference, I found there is an "Object" in the memcache Item:
// Object is the Item's value for use with a Codec.
Object interface{}
That seems to be a built-in mechanic to store an object in memcache. However, the gae documentation did not provide a sample code.
Could anyone please show me an example? Thanks in advance

OK, I just figured it out my self. The memcache pkg has two built-in Codec: gob and json. Just use one of them (or of course one can create his own Codec):
var in, out struct {I int;}
// Put in into memcache
in.I = 100
item := &memcache.Item {
Key: "TestKey",
Object: in,
}
memcache.Gob.Set(c, item) // error checking omitted for convenience
// retrieve the value
memcache.Gob.Get(c, "TestKey", &out)
fmt.Fprint(w, out) // will print {100}
Thanks all

Related

Realm object in array?

Question
How can I create an array of objects containing Realm objects?
Code
let realm = try! Realm()
let data: [A] = realm.objects(A)
Error
Cannot invoke 'objects' with an argument list of type '(Object.type)'
How can I create an array of objects containing Realm objects?
From your code sample, I'll further assume that you want to make an array from a Realm Results, not just "standalone" Realm objects.
Since Results conforms to SequenceType, you can use SequenceType.map() to convert it into an array:
let arrayFromResults = results.map({ $0 })
Note, however, that this is almost always the wrong pattern to use.
From your tweet on the same topic, a preferable way to do this would be to encode what you want to display on screen as a Realm query:
self.results = realm.objects(A).filter("poppedOff == NO")
And "popping off" an object (whatever that means) would update the poppedOff property of that object.
Since Realm Results are auto-updating, this won't risk getting out of sync with the contents of the Realm, unlike the array conversion approach, which would have to be updated on every Realm change notification.

BreezeJS: Change Enum Text Values in MetadataStore

I'm absolutely loving BreezeJS and was so surprised to see that my Enum values were being displayed as their text values and not their ordinal ones! What I would love to be able to do is, on the client side, open the MetadataStore, fetch the enumeration and modify it's textual properties for display purposes.
Is this currently possible? From my research it would appear not, but I'm wondering if there is perhaps a simple workaround. Everything I've tried has involved a large number of hacks and server-side attributes, but to no avail, or the solution just seemed overly complex and not worth the benefits.
Here is what I said about how to get the enum values from raw metadata in another SO comment.
The enum values are available in the metadata generated by EF and sent to a Breeze client. I agree Breeze should pick them up automatically and put them somewhere so you don't have to make a separate request for them or extract them from the raw metadata passed to the MetadataStore.fetchMetadata success callback. It's on our backlog.
Meanwhile, you'll have to get them by hand. There is a DocCode test that shows how:
/*********************************************************
* Can can get enum types from raw EF-generated metadata
* Related to feature request #2271: Extract enum values from server metadata
*************************************************************/
asyncTest("can get enum type from raw EF-generated metadata", function() {
var serviceName = testFns.foosMetadataServiceName;
var store = new breeze.MetadataStore();
store.fetchMetadata(serviceName)
.then(metaSuccess, metaFail).fail(handleFail).fin(start);
function metaSuccess(rawMetadata) {
ok(true, "foos metadata fetched");
var enumType = rawMetadata.schema && rawMetadata.schema.enumType;
if (enumType && enumType.name ==='Color') {
var members = enumType.member;
ok(members.length,
"should have several members; members are: " + JSON.stringify(members));
} else {
ok(false, "metadata should have had one enumType, 'Color'.");
}
}
function metaFail(error) {
ok(false, "foos metadata fetch failed: " + error.message);
}
});
we're using Breeze with NHibernate and wand to do the same. Metadata generated for NHibernate are standard breeze Metadata and doesn't contain the Schema part. Any ideas how to do it?
edit: To fix our issue I added a list of all used enums in the metadata(like the structuralTypes node). Then we cache it on the client when the metadata are retrieved.
https://github.com/lnu/breeze.server.net/commit/65ad687ad13c4dd9f4a6ab6a3ed09e407e2b58ec
Thanks

Implementing get_multi on app engine memcache

I was wondering if somebody could help. I'm using the blobcache module outlined in this post here
This works fine but I'm looking to speed retrieval from memcache by using the get_multi()
key function but my current code cannot find the keys when using get_multi
My current get def looks like this
def get(key):
chunk_keys = memcache.get(key)
if chunk_keys is None:
return None
chunk_keys= ",".join(chunk_keys)
str(chunk_keys)
chunk = memcache.get_multi(chunk_keys)
if chunk is None:
return None
try:
return chunk
except Exception:
return None
My understanding per the documentation is that you only need to pass through a string of keys to get_multi.
However his is not returning anything at the moment.
Can someone point out what i'm doing wrong here?
pass it a list of strings (keys) , instead of a single string with commas in it.
get_multi(keys, key_prefix='', namespace=None, for_cas=False)
keys = List of keys to look up. A Key can be a string or a tuple of
(hash_value, string), where the hash_value, normally used for sharding
onto a memcache instance, is instead ignored, as Google App Engine
deals with the sharding transparently.
Multi Get Documentation

Google App Engine Memcache Object Types

Very short questions : Can I only store objects of type Entity in GAE's memcache or does it support other types ?
Thanks
For Java you can use every object that implements java.Serializable as stated in the Javadoc https://developers.google.com/appengine/docs/java/javadoc/com/google/appengine/api/memcache/MemcacheService
For Python: according to the source, any type is acceptable.
def add(self, key, value, time=0, min_compress_len=0, namespace=None):
"""Sets a key's value, iff item is not already in memcache.
Args:
key: Key to set. See docs on Client for details.
value: Value to set. Any type. If complex, will be pickled.
...

Updating entity in Google Appengine datastore with Go

I am toying with GAE, Go and the datastore. I have the following structs:
type Coinflip struct {
Participants []*datastore.Key
Head string
Tail string
Done bool
}
type Participant struct {
Email string
Seen datastore.Time
}
(For those wondering I store Participants as a slice off Key pointers because Go doesn't automatically dereferences entities.)
Now I want to find a Participant with a particular Email address associated with a know Coinflip. Like so (this works):
coinflip, _ := find(key_as_string, context)
participants, _ := coinflip.fetchParticipants(context) /* a slice of Participant*/
var found *Participant
for i := 0; i < len(participants) && found == nil; i++ {
if participants[i].Email == r.FormValue("email") {
found = &participants[i]
}
}
(*found).Seen = datastore.SecondsToTime(time.Seconds())
How do I save *found to the datastore? I need the key apparently but the coupling between the Participant struct and the Key is very loose.
I'm unsure how to proceed from here. Do I need to return the keys as well from the fetchParticipants call? The Java and Python GAE implementation seem quite a bit simpler (just call put() on the object).
Thanks in advance,
Do I need to return the keys as well from the fetchParticipants call?
Yes. And then call "func Put(c appengine.Context, key *Key, src interface{}) (*Key, os.Error)"
The Java and Python GAE implementation seem quite a bit simpler (just
call put() on the object).
Probably a fair statement. The Go community has a very strong bias against "magic". In this case the Participant struct has two fields that you have declared. Adding the key to it in the background would be considered magic.
For interacting with data in Go, consider using our new library https://github.com/matryer/gae-records for an Active Record, data objects wrapper around the datastore. It sorts out a lot of the hassle for you.
For example, it supports:
// create a new model for 'People'
People := gaerecords.NewModel("People")
// create a new person
mat := People.New()
mat.
SetString("name", "Mat")
SetInt64("age", 28)
.Put()
// load person with ID 1
person, _ := People.Find(1)
// change some fields
person.SetInt64("age", 29).Put()
// load all People
peeps, _ := People.FindAll()
// delete mat
mat.Delete()
// delete user with ID 2
People.Delete(2)
// find the first three People by passing a func(*datastore.Query)
// to the FindByQuery method
firstThree, _ := People.FindByQuery(func(q *datastore.Query){
q.Limit(3)
})
// build your own query and use that
var ageQuery *datastore.Query = People.NewQuery().
Limit(3).Order("-age")
// use FindByQuery with a query object
oldestThreePeople, _ := People.FindByQuery(ageQuery)
// using events, make sure 'People' records always get
// an 'updatedAt' value set before being put (created and updated)
People.BeforePut.On(func(c *gaerecords.EventContext){
person := c.Args[0].(*Record)
person.SetTime("updatedAt", datastore.SecondsToTime(time.Seconds()))
})

Resources