Skip to content
This repository was archived by the owner on Mar 16, 2020. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

a google reader clone built with go on app engine and angularjs

# Current build instructions:
* Use this:
Building: `GOPATH=$(GOPATH) GO111MODULE=auto go build app.go`
Deploy: `GOPATH=$(GOPATH) gcloud beta app deploy`

## setting up a local dev environment

1. Install [Python 2.7](http://www.python.org/download/releases/2.7.5/) and make sure it is in your `PATH`. (Google App Engine doesn't yet work with Python 3.)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ import (
"fmt"
"net/http"

"appengine"
"appengine/memcache"
"appengine/user"
"appengine_internal"
"golang.org/x/net/context"
"google.golang.org/appengine/v2"
"google.golang.org/appengine/v2/memcache"
"google.golang.org/appengine/v2/user"
"github.com/mjibson/goread/_third_party/github.com/MiniProfiler/go/miniprofiler"
"github.com/mjibson/goread/_third_party/github.com/mjibson/appstats"
)
Expand Down Expand Up @@ -84,16 +84,17 @@ type Context struct {
miniprofiler.Timer
}

func (c Context) Call(service, method string, in, out appengine_internal.ProtoMessage, opts *appengine_internal.CallOptions) (err error) {
/*
func (c Context) Call(service, method string, in, out internal.Proto.Message) (err error) {
if c.Timer != nil && service != "__go__" {
c.StepCustomTiming(service, method, fmt.Sprintf("%v\n\n%v", method, in.String()), func() {
err = c.Context.Call(service, method, in, out, opts)
err = c.Context.Call(service, method, in, out)
})
} else {
err = c.Context.Call(service, method, in, out, opts)
err = c.Context.Call(service, method, in, out)
}
return
}
}*/

func (c Context) Step(name string, f func(Context)) {
if c.Timer != nil {
Expand All @@ -110,7 +111,7 @@ func (c Context) Step(name string, f func(Context)) {

// NewHandler returns a profiled, appstats-aware appengine.Context.
func NewHandler(f func(Context, http.ResponseWriter, *http.Request)) http.Handler {
return appstats.NewHandler(func(c appengine.Context, w http.ResponseWriter, r *http.Request) {
return appstats.NewHandler(func(c context.Context, w http.ResponseWriter, r *http.Request) {
h := miniprofiler.NewHandler(func(t miniprofiler.Timer, w http.ResponseWriter, r *http.Request) {
pc := Context{
Context: c.(appstats.Context),
Expand Down
43 changes: 22 additions & 21 deletions _third_party/github.com/mjibson/appstats/appstats.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ import (
"math/rand"
"net/http"
"net/url"
"runtime/debug"
"time"

"appengine"
"appengine/memcache"
"appengine/user"
"appengine_internal"
"golang.org/x/net/context"
"google.golang.org/appengine/v2"
"google.golang.org/appengine/v2/log"
"google.golang.org/appengine/v2/memcache"
"google.golang.org/appengine/v2/user"
)

var (
Expand Down Expand Up @@ -69,20 +69,21 @@ func DefaultShouldRecord(r *http.Request) bool {
return rand.Float64() < RecordFraction
}

// Context is a timing-aware appengine.Context.
// Context is a timing-aware context.Context.
type Context struct {
appengine.Context
context.Context
header http.Header
stats *requestStats
}

// Call times an appengine.Context Call. Internal use only.
func (c Context) Call(service, method string, in, out appengine_internal.ProtoMessage, opts *appengine_internal.CallOptions) error {
// Call times an context.Context Call. Internal use only.
/*
func (c Context) Call(service, method string, in, out internal.Proto.Message) error {
c.stats.wg.Add(1)
defer c.stats.wg.Done()

if service == "__go__" {
return c.Context.Call(service, method, in, out, opts)
return c.Context.Call(service, method, in, out)
}

stat := rpcStat{
Expand All @@ -92,7 +93,7 @@ func (c Context) Call(service, method string, in, out appengine_internal.ProtoMe
Offset: time.Since(c.stats.Start),
StackData: string(debug.Stack()),
}
err := c.Context.Call(service, method, in, out, opts)
err := c.Context.Call(service, method, in, out)
stat.Duration = time.Since(stat.Start)
stat.In = in.String()
stat.Out = out.String()
Expand All @@ -110,7 +111,7 @@ func (c Context) Call(service, method string, in, out appengine_internal.ProtoMe
c.stats.Cost += stat.Cost
c.stats.lock.Unlock()
return err
}
}*/

// NewContext creates a new timing-aware context from req.
func NewContext(req *http.Request) Context {
Expand All @@ -137,7 +138,7 @@ func NewContext(req *http.Request) Context {

// WithContext enables profiling of functions without a corresponding request,
// as in the appengine/delay package. method and path may be empty.
func WithContext(context appengine.Context, method, path string, f func(Context)) {
func WithContext(context context.Context, method, path string, f func(Context)) {
var uname string
var admin bool
if u := user.Current(context); u != nil {
Expand Down Expand Up @@ -170,7 +171,7 @@ func (c Context) save() {
Stats: c.stats,
}
if err := gob.NewEncoder(&buf_full).Encode(&full); err != nil {
c.Errorf("appstats Save error: %v", err)
log.Errorf(c.Context, "appstats Save error: %v", err)
return
} else if buf_full.Len() > bufMaxLen {
// first try clearing stack traces
Expand All @@ -187,7 +188,7 @@ func (c Context) save() {
part.RPCStats[i].Out = ""
}
if err := gob.NewEncoder(&buf_part).Encode(&part); err != nil {
c.Errorf("appstats Save error: %v", err)
log.Errorf(c.Context, "appstats Save error: %v", err)
return
}

Expand All @@ -201,7 +202,7 @@ func (c Context) save() {
Value: buf_full.Bytes(),
}

c.Infof("Saved; %s: %s, %s: %s, link: %v",
log.Infof(c.Context, "Saved; %s: %s, %s: %s, link: %v",
item_part.Key,
byteSize(len(item_part.Value)),
item_full.Key,
Expand All @@ -222,31 +223,31 @@ func (c Context) URL() string {
return u.String()
}

func (c Context) storeContext() appengine.Context {
func (c Context) storeContext() context.Context {
nc, _ := appengine.Namespace(c.Context, Namespace)
return nc
}

func context(r *http.Request) appengine.Context {
func _context(r *http.Request) context.Context {
c := appengine.NewContext(r)
nc, _ := appengine.Namespace(c, Namespace)
return nc
}

// handler is an http.Handler that records RPC statistics.
type handler struct {
f func(appengine.Context, http.ResponseWriter, *http.Request)
f func(context.Context, http.ResponseWriter, *http.Request)
}

// NewHandler returns a new Handler that will execute f.
func NewHandler(f func(appengine.Context, http.ResponseWriter, *http.Request)) http.Handler {
func NewHandler(f func(context.Context, http.ResponseWriter, *http.Request)) http.Handler {
return handler{
f: f,
}
}

// NewHandlerFunc returns a new HandlerFunc that will execute f.
func NewHandlerFunc(f func(appengine.Context, http.ResponseWriter, *http.Request)) http.HandlerFunc {
func NewHandlerFunc(f func(context.Context, http.ResponseWriter, *http.Request)) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
h := handler{
f: f,
Expand Down
12 changes: 6 additions & 6 deletions _third_party/github.com/mjibson/appstats/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ import (
"strings"
"time"

"appengine"
"appengine/memcache"
"appengine/user"
"google.golang.org/appengine/v2"
"google.golang.org/appengine/v2/memcache"
"google.golang.org/appengine/v2/user"
)

var templates *template.Template
Expand Down Expand Up @@ -91,7 +91,7 @@ func index(w http.ResponseWriter, r *http.Request) {
keys[i] = fmt.Sprintf(keyPart, i*distance)
}

c := context(r)
c := _context(r)
items, err := memcache.GetMulti(c, keys)
if err != nil {
return
Expand Down Expand Up @@ -238,7 +238,7 @@ func details(w http.ResponseWriter, r *http.Request) {
qtime := roundTime(i)
key := fmt.Sprintf(keyFull, qtime)

c := context(r)
c := _context(r)

v := struct {
Env map[string]string
Expand Down Expand Up @@ -306,7 +306,7 @@ func file(w http.ResponseWriter, r *http.Request) {
fname := r.URL.Query().Get("f")
n := r.URL.Query().Get("n")
lineno, _ := strconv.Atoi(n)
c := context(r)
c := _context(r)

f, err := ioutil.ReadFile(fname)
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions _third_party/github.com/mjibson/goon/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ datastore:
type Group struct {
Name string
}
c := appengine.NewContext(r)
c := r.NewContext()
g := &Group{Name: "name"}
k := datastore.NewIncompleteKey(c, "Group", nil)
err := datastore.Put(c, k, g)
Expand All @@ -110,7 +110,7 @@ datastore:
type Group struct {
Name string
}
c := appengine.NewContext(r)
c := r.NewContext()
g := &Group{}
k := datastore.NewKey(c, "Group", "", 1, nil)
err := datastore.Get(c, k, g)
Expand Down
4 changes: 2 additions & 2 deletions _third_party/github.com/mjibson/goon/entity.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ import (
"sync"
"time"

"appengine"
"appengine/datastore"
"google.golang.org/appengine/v2"
"google.golang.org/appengine/v2/datastore"
)

type fieldInfo struct {
Expand Down
33 changes: 19 additions & 14 deletions _third_party/github.com/mjibson/goon/goon.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,18 @@ import (
"sync"
"time"

"appengine"
"appengine/datastore"
"appengine/memcache"
"golang.org/x/net/context"

"google.golang.org/appengine/v2"
"google.golang.org/appengine/v2/log"
"google.golang.org/appengine/v2/datastore"
"google.golang.org/appengine/v2/memcache"
)

var (
// LogErrors issues appengine.Context.Errorf on any error.
// LogErrors issues context.Context.Errorf on any error.
LogErrors = true
// LogTimeoutErrors issues appengine.Context.Warningf on memcache timeout errors.
// LogTimeoutErrors issues context.Context.Warningf on memcache timeout errors.
LogTimeoutErrors = false

// MemcachePutTimeoutThreshold is the number of bytes at which the memcache
Expand All @@ -53,7 +56,7 @@ var (

// Goon holds the app engine context and the request memory cache.
type Goon struct {
Context appengine.Context
Context context.Context
cache map[string]interface{}
cacheLock sync.RWMutex // protect the cache from concurrent goroutines to speed up RPC access
inTransaction bool
Expand All @@ -75,9 +78,9 @@ func NewGoon(r *http.Request) *Goon {
return FromContext(appengine.NewContext(r))
}

// FromContext creates a new Goon object from the given appengine Context.
// FromContext creates a new Goon object from the given context Context.
// Useful with profiling packages like appstats.
func FromContext(c appengine.Context) *Goon {
func FromContext(c context.Context) *Goon {
return &Goon{
Context: c,
cache: make(map[string]interface{}),
Expand All @@ -91,15 +94,15 @@ func (g *Goon) error(err error) {
}
_, filename, line, ok := runtime.Caller(1)
if ok {
g.Context.Errorf("goon - %s:%d - %v", filepath.Base(filename), line, err)
log.Errorf(g.Context, "goon - %s:%d - %v", filepath.Base(filename), line, err)
} else {
g.Context.Errorf("goon - %v", err)
log.Errorf(g.Context, "goon - %v", err)
}
}

func (g *Goon) timeoutError(err error) {
if LogTimeoutErrors {
g.Context.Warningf("goon memcache timeout: %v", err)
log.Warningf(g.Context, "goon memcache timeout: %v", err)
}
}

Expand Down Expand Up @@ -158,7 +161,7 @@ func (g *Goon) KeyError(src interface{}) (*datastore.Key, error) {
// https://developers.google.com/appengine/docs/go/datastore/reference#RunInTransaction
func (g *Goon) RunInTransaction(f func(tg *Goon) error, opts *datastore.TransactionOptions) error {
var ng *Goon
err := datastore.RunInTransaction(g.Context, func(tc appengine.Context) error {
err := datastore.RunInTransaction(g.Context, func(tc context.Context) error {
ng = &Goon{
Context: tc,
inTransaction: true,
Expand Down Expand Up @@ -346,7 +349,8 @@ func (g *Goon) putMemcache(srcs []interface{}, exists []byte) error {
}
errc := make(chan error)
go func() {
errc <- memcache.SetMulti(appengine.Timeout(g.Context, memcacheTimeout), items)
c, _ := context.WithTimeout(g.Context, memcacheTimeout)
errc <- memcache.SetMulti(c, items)
}()
g.putMemoryMulti(srcs, exists)
err := <-errc
Expand Down Expand Up @@ -440,7 +444,8 @@ func (g *Goon) GetMulti(dst interface{}) error {

multiErr, any := make(appengine.MultiError, len(keys)), false

memvalues, err := memcache.GetMulti(appengine.Timeout(g.Context, MemcacheGetTimeout), memkeys)
c, _ := context.WithTimeout(g.Context, MemcacheGetTimeout)
memvalues, err := memcache.GetMulti(c, memkeys)
if appengine.IsTimeoutError(err) {
g.timeoutError(err)
err = nil
Expand Down
8 changes: 4 additions & 4 deletions _third_party/github.com/mjibson/goon/goon_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ import (
"testing"
"time"

"appengine"
"appengine/aetest"
"appengine/datastore"
"appengine/memcache"
"google.golang.org/appengine/v2"
"google.golang.org/appengine/v2/aetest"
"google.golang.org/appengine/v2/datastore"
"google.golang.org/appengine/v2/memcache"
)

// *[]S, *[]*S, *[]I, []S, []*S, []I
Expand Down
2 changes: 1 addition & 1 deletion _third_party/github.com/mjibson/goon/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
"fmt"
"reflect"

"appengine/datastore"
"google.golang.org/appengine/v2/datastore"
)

// Count returns the number of results for the query.
Expand Down
Loading