GAE/Go機能紹介

Google App Engint/Go Introduction

20 December 2014

Daigo Ikeda

Knightso, LLC

GAEとは

2

GAE/Goの特徴

3

速い!

特にspin-upが。

もちろん実行速度も。

4

Built-in Concurrency!

平行処理をシンプルに書ける→パフォーマンスチューニングが容易
つまり課金が抑えられる!!

5

現状(2014/12現在)

6

各機能紹介

7

Datastore

8

Datastoreとは

9

Datastore - KeyでのPut

type Book struct {
    Title     string
    Author    string
    Price     int
    CreatedAt time.Time
}
    book := Book{
        "Perfect Go",
        "Some Gopher",
        1000,
        time.Now(),
    }
    key := datastore.NewKey(c, "Book", "book1", 0, nil)
    //key := datastore.NewIncompleteKey(c, "Book", nil) // 自動ID付与
    key, err := datastore.Put(c, key, &book)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
10

Datastore - KeyでのPut(複数)

    keys := make([]*datastore.Key, 10)
    for i, _ := range keys {
        keys[i] = datastore.NewKey(c, "Book", "", int64(i+1), nil)
    }

    books := make([]Book, 10)
    for i, _ := range books {
        number := i + 1
        books[i] = Book{
            fmt.Sprintf("book-%d", number),
            fmt.Sprintf("author-%d", number%2),
            number * 100,
            time.Now(),
        }
    }
    _, err := datastore.PutMulti(c, keys, books)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
11

Datastore - KeyでのGet

    key := datastore.NewKey(c, "Book", "book1", 0, nil)

    var book Book
    err := datastore.Get(c, key, &book)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
12

Datastore - KeyでのGet(複数)

    keys := make([]*datastore.Key, 10)
    for i, _ := range keys {
        keys[i] = datastore.NewKey(c, "Book", "", int64(i+1), nil)
    }

    books := make([]Book, 10)
    err := datastore.GetMulti(c, keys, books)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
13

Datastore - Query(検索)

    q := datastore.NewQuery("Book").Filter("Author=", "author-1").Order("-CreatedAt").Offset(2).Limit(5)

    var books []Book
    keys, err := q.GetAll(c, &books)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
14

Datastore - 複合インデックス設定

indexes:

# AUTOGENERATED

- kind: Book
  properties:
  - name: Author
  - name: CreatedAt
    direction: desc

- kind: Book
  properties:
  - name: Title
  - name: CreatedAt
    direction: desc
15

Datastore - Query(カーソル)

    q := datastore.NewQuery("Book").Filter("Author=", "author-1").Order("-CreatedAt")

    pCursor := r.FormValue("cursor")
    if pCursor != "" {
        cursor, err := datastore.DecodeCursor(pCursor)
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }
        q.Start(cursor)
    }
16

    var books []Book

    t := q.Run(c)
    for i := 0; i < 10; i++ {
        var book Book
        key, err := t.Next(&book)
        if err == datastore.Done {
            break
        }
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }

        c.Debugf("#v", key)

        books = append(books, book)
    }
    response.Books = books
    if cursor, err := t.Cursor(); err == nil {
        response.Cursor = cursor.String()
    }
17

Datastore - トランザクション

    key := datastore.NewKey(c, "Book", "book1", 0, nil)

    if err := datastore.RunInTransaction(c, func(c appengine.Context) error {
        var book Book
        if err := datastore.Get(c, key, &book); err != nil {
            return err
        }

        book.Price += 200

        if _, err := datastore.Put(c, key, &book); err != nil {
            return err
        }

        return nil
    }, nil); err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
18

19

Memcache

20

Memcacheとは

21

Memcache - Set

    item := memcache.Item{
        Key:   "test1",
        Value: []byte("hello memcache"),
    }
    if err := memcache.Set(c, &item); err != nil {
        fmt.Fprintf(w, "failure: %s", err)
    } else {
        fmt.Fprint(w, "success")
    }
22

Memcache - Get

    item, err := memcache.Get(c, "test1")
    if err != nil {
        w.Write([]byte("not found"))
        return
    }
23

Memcache - Set Gob

    book := Book{
        "Perfect Go",
        "Some Gopher",
        1000,
        time.Now(),
    }

    item := memcache.Item{
        Key:    "book1",
        Object: &book,
    }
    if err := memcache.Gob.Set(c, &item); err != nil {
        fmt.Fprintf(w, "failure: %s", err)
    } else {
        w.Write([]byte("success"))
    }
24

Memcache - Get Gob

    var book Book
    _, err := memcache.Gob.Get(c, "book1", &book)
    if err != nil {
        w.Write([]byte("not found"))
        return
    }
25

Memcache - その他

goon

nds

26

Search

27

Searchとは

28

Search - 保存

    index, err := search.Open("Book")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    for i, book := range books {
        _, err := index.Put(c, fmt.Sprintf("book%d", i), book)
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }
    }
29

Search - 検索

    index, err := search.Open("Book")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    books := make([]*Book, 0, 10)
    t := index.Search(c, "Gopher Price >= 3000", nil)
    for {
        var book Book
        _, err := t.Next(&book)
        if err == search.Done {
            break
        } else if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }
        books = append(books, &book)
    }
30

URL Fetch

31

URL Fetch

32

URL Fetch - fetch

    client := urlfetch.Client(c)
    resp, err := client.Get("http://www.google.com/")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    var buf bytes.Buffer
    if _, err := io.Copy(&buf, resp.Body); err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
33

Mail

34

Mail

35

Mail - 送信

    msg := &mail.Message{
        Sender:  "Hoge <hoge@example.com>",
        To:      []string{"to@example.com"},
        Subject: "This is test mail.",
        Body:    "Hello Gopher!",
    }

    if err := mail.Send(c, msg); err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
36

Mail - 受信

app.yaml

- url: /_ah/mail/.*
  script: _go_app
  login: admin

inbound_services:
- mail
    http.HandleFunc("/_ah/mail/", receive)
    defer r.Body.Close()

    var b bytes.Buffer
    if _, err := b.ReadFrom(r.Body); err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
37

38

Cron

39

Cron - スケジュールタスク実行

cron.yaml

cron:
- description: daily summary job
  url: /tasks/summary
  schedule: every 24 hours
- description: monday morning mailout
  url: /mail/weekly
  schedule: every monday 09:00
  timezone: Australia/NSW
- description: new daily summary job
  url: /tasks/summary
  schedule: every 24 hours
  target: beta
40

その他の機能

41

その他の機能

42

最後に

FYI:

GAE/Goハンズオン

弊社開発ブログ

43

Thank you

Daigo Ikeda

Knightso, LLC

Use the left and right arrow keys or click the left and right edges of the page to navigate between slides.
(Press 'H' or navigate to hide this message.)