Skip to content

Instantly share code, notes, and snippets.

@swdunlop
Created November 28, 2019 05:45
Show Gist options
  • Save swdunlop/f3eb1ef5aeeeda5a9e9866ef948ff80b to your computer and use it in GitHub Desktop.
Save swdunlop/f3eb1ef5aeeeda5a9e9866ef948ff80b to your computer and use it in GitHub Desktop.
Simple Time Server Using GQLGen
package main
import (
"context"
"net/http"
"strings"
"time"
"github.com/99designs/gqlgen/handler"
)
//go:generate go run github.com/99designs/gqlgen
func main() {
playgroundHandler := handler.Playground("What Time is It?", `/graphql`)
exec := NewExecutableSchema(Config{Resolvers: root{}})
graphqlHandler := handler.GraphQL(exec)
http.HandleFunc("/graphql", func(w http.ResponseWriter, r *http.Request) {
switch {
case r.Method != `GET`:
graphqlHandler.ServeHTTP(w, r)
case canUpgrade(r, `websocket`):
graphqlHandler.ServeHTTP(w, r)
default:
playgroundHandler.ServeHTTP(w, r)
}
})
err := http.ListenAndServe(`localhost:8080`, nil)
if err != nil {
panic(err)
}
}
func canUpgrade(r *http.Request, protocol string) bool {
for _, v := range r.Header[`Upgrade`] {
if strings.SplitN(v, " ", 2)[0] == protocol {
return true
}
}
return false
}
type root struct{}
func (_ root) Query() QueryResolver { return query{} }
func (_ root) Subscription() SubscriptionResolver { return subscription{} }
type query struct{}
func (_ query) Time(_ context.Context) (string, error) {
return time.Now().Format(timeFormat), nil
}
type subscription struct{}
func (r subscription) TimeChanged(ctx context.Context) (<-chan string, error) {
ret := make(chan string)
go r.trackTimeChanges(ctx, ret)
return ret, nil
}
func (r subscription) trackTimeChanges(ctx context.Context, ret chan<- string) {
t := time.NewTicker(time.Second)
defer t.Stop()
start := time.Now().Format(timeFormat)
println(`.. starting to track time changes at`, start)
defer println(`.. done tracking time changes since`, start)
done := ctx.Done()
select {
case <-done:
return
case ret <- start:
}
for {
select {
case <-done:
return
case t := <-t.C:
now := t.Format(timeFormat)
select {
case <-done:
return
case ret <- now:
}
}
}
}
const timeFormat = `2006-01-02 15:04:05`
package main
import (
"context"
"net/http"
"strings"
"time"
"github.com/99designs/gqlgen/handler"
)
//go:generate go run github.com/99designs/gqlgen
func main() {
playgroundHandler := handler.Playground("What Time is It?", `/graphql`)
exec := NewExecutableSchema(Config{Resolvers: root{}})
graphqlHandler := handler.GraphQL(exec)
http.HandleFunc("/graphql", func(w http.ResponseWriter, r *http.Request) {
switch {
case r.Method != `GET`:
graphqlHandler.ServeHTTP(w, r)
case canUpgrade(r, `websocket`):
graphqlHandler.ServeHTTP(w, r)
default:
playgroundHandler.ServeHTTP(w, r)
}
})
err := http.ListenAndServe(`localhost:8080`, nil)
if err != nil {
panic(err)
}
}
func canUpgrade(r *http.Request, protocol string) bool {
for _, v := range r.Header[`Upgrade`] {
if strings.SplitN(v, " ", 2)[0] == protocol {
return true
}
}
return false
}
type root struct{}
func (_ root) Query() QueryResolver { return query{} }
func (_ root) Subscription() SubscriptionResolver { return subscription{} }
type query struct{}
func (_ query) Time(_ context.Context) (string, error) {
return time.Now().Format(timeFormat), nil
}
type subscription struct{}
func (r subscription) TimeChanged(ctx context.Context) (<-chan string, error) {
ret := make(chan string)
go r.trackTimeChanges(ctx, ret)
return ret, nil
}
func (r subscription) trackTimeChanges(ctx context.Context, ret chan<- string) {
t := time.NewTicker(time.Second)
defer t.Stop()
start := time.Now().Format(timeFormat)
println(`.. starting to track time changes at`, start)
defer println(`.. done tracking time changes since`, start)
done := ctx.Done()
select {
case <-done:
return
case ret <- start:
}
for {
select {
case <-done:
return
case t := <-t.C:
now := t.Format(timeFormat)
select {
case <-done:
return
case ret <- now:
}
}
}
}
const timeFormat = `2006-01-02 15:04:05`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment