Sto scrivendo un'applicazione Go per l'esecuzione sul runtime Go di App Engine.Come posso gestire il contesto di runtime di App Engine Go per evitare il blocco di App Engine?
Ho notato che praticamente qualsiasi operazione che utilizza un servizio di App Engine (come archivio dati, posta, o anche Capabilities) richiede che si passa un'istanza di appengine.Context
che deve essere recuperato utilizzando la funzione appengine.NewContext(req *http.Request) Context
.
Mentre scrivo questa app per App Engine, voglio essere in grado di spostarla su un'altra piattaforma (probabilmente una che non supporta alcuna API di App Engine) in modo facile e veloce se dovessi scegliere.
Quindi, sto astromettendo l'interazione effettiva con i servizi App Engine e le API scrivendo piccoli involucri attorno a qualsiasi interazione specifica di App-Engine (incluse le funzioni di gestione delle richieste). Con questo approccio, se mai mi piacerebbe passare a una piattaforma diversa, mi limiterò a riscrivere quei moduli specifici che legano la mia applicazione a App Engine. Facile e diretto
L'unico problema è l'oggetto appengine.Context
. Non posso passarlo dai miei gestori di richieste attraverso i miei livelli di logica ai moduli che gestiscono queste API senza legare praticamente tutto il mio codice a App Engine. Potrei passare l'oggetto http.Request
da cui è possibile ricavare l'oggetto appengine.Context
, ma ciò richiederebbe l'accoppiamento di cose che probabilmente non dovrebbero essere accoppiate. (Penso che sia meglio per nessuna delle mie applicazioni sapere che si tratta di un'applicazione web eccetto quelle parti specificamente dedicate alla gestione delle richieste HTTP.)
La prima soluzione che è venuta alla mente è stata creare una variabile persistente in qualche modulo . Qualcosa di simile a questo:
package context
import (
"appengine"
)
var Context appengine.Context
Poi, nella mia richiesta gestori, posso impostare questa variabile con context.Context = appengine.NewContext(r)
e nei moduli che utilizzano direttamente App Engine servizi, posso prendere il contesto da accesing context.Context
. Nessuno dei codici che intervengono avrebbe bisogno di sapere dell'esistenza dell'oggetto appengine.Context
. L'unico problema è che "multiple requests may be handled concurrently by a given instance", che può portare a condizioni di gara e comportamento imprevisto con questo piano. (Una richiesta imposta, un altro set di esso, il primo si accede e ottiene l'appengine.Context
oggetto sbagliato.)
ho potuto in teoria memorizzare il appengine.Context
al datastore, ma poi avrei dovuto passare un po 'identificativo specifico-request giù i livelli logici per i moduli specifici del servizio che identificano quale oggetto appengine.Context
in datastore è quello per la richiesta corrente, che accoppierà di nuovo le cose che non penso dovrebbero essere accoppiate. (E, aumenterebbe l'uso datastore della mia applicazione.)
Potrei anche passare l'oggetto appengine.Context
verso il basso l'intera catena logica con il tipo interface{}
per tutta la strada e hanno tutti i moduli che non ha bisogno l'oggetto appengine.Context
ignorarlo. Ciò eviterebbe di legare la maggior parte della mia applicazione a qualsiasi specifico. Ciò sembra anche molto disordinato, comunque.
Quindi, sono un po 'incerto su come garantire in modo pulito che i moduli specifici di App-Engine che necessitano l'oggetto appengine.Context
possano ottenerlo. Spero che voi gente possa darmi una soluzione che devo ancora pensare a me stesso.
Grazie in anticipo!
Grazie per la risposta! Penso di avere un'idea che potrebbe funzionare per la mia particolare applicazione. Non sono sicuro che funzioni in generale, ma potrebbe funzionare per una percentuale significativa di app di App Engine. Se la mia idea finisce per essere una soluzione semi-generale, la rilascerò definitivamente come un progetto open source. : D – AntiMS
La maggior parte della mia applicazione ha accesso a un ID utente o a un ID di sessione. Il mio piano è solo quello di creare una mappa persistente basata su valori derivati direttamente da un id di sessione o da un id utente. I gestori delle richieste possono creare e archiviare gli oggetti di contesto e i moduli che richiedono un contesto possono recuperarli in modo simile. Non sono completamente sicuro che funzionerà, comunque. (Potrebbero esserci alcuni moduli che non hanno accesso a un ID di sessione o id utente. In alcuni di questi casi potrei dover essere creativo.) – AntiMS