%
% Copyright (C) 2015-2016 Sebastian 'tokkee' Harl <sh@tokkee.org>
% All rights reserved.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions
% are met:
% 1. Redistributions of source code must retain the above copyright
%    notice, this list of conditions and the following disclaimer.
% 2. Redistributions in binary form must reproduce the above copyright
%    notice, this list of conditions and the following disclaimer in the
%    documentation and/or other materials provided with the distribution.
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
% ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
% TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
% PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
% CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
% EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
% PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
% OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
% WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
% OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
% ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
%
\documentclass[presentation]{beamer}
\uselanguage{German}

\usetheme{tokkee}
\usefonttheme{professionalfonts}

\setbeamercolor*{block body}{fg=black,bg=white}
\setbeamercolor*{block title}{use=titlelike,fg=titlelike.fg!80!black,bg=black!10}

\usepackage{fontspec,xunicode,polyglossia}
\setdefaultlanguage[spelling=new]{german}

\usepackage{graphicx}
\usepackage{xcolor}
\definecolor{darkgreen}{rgb}{0,0.39,0}

\usepackage{listings}
\lstset{
  basicstyle=\scriptsize,
  language=Go,
  frame=single,
  numbers=left,
  keywordstyle=\bfseries\color{darkgreen},
  commentstyle=\itshape\color{blue},
  stringstyle=\color{red},
  showstringspaces=false,
  backgroundcolor=\color{lightgray!25},
  literate=%
    {Ö}{{\"O}}1
    {Ä}{{\"A}}1
    {Ü}{{\"U}}1
    {ß}{{\ss}}1
    {ü}{{\"u}}1
    {ä}{{\"a}}1
    {ö}{{\"o}}1,
}

\usepackage[overlay,absolute]{textpos}

\usepackage{tikz}
\usetikzlibrary{shadows}
\usetikzlibrary{shapes}

\newcommand{\collectd}{\textsf{\textbf{collect}d}}

\title{Web-Services mit Go}
\subtitle{Go-Features an Hand von Beispielen}

\titlegraphic{}

\copyrightinfo{\copyright{} 2015-2016 Sebastian `tokkee' Harl}

\author[Sebastian Harl]{Sebastian `tokkee' Harl\\
  $<$sh@tokkee.org$>$}

\date[2015-2016]{}

\AtBeginSection[]
{
  \begin{frame}
    \begin{center}
      \Large
      \titlebox{\secname}
    \end{center}
  \end{frame}
}

\begin{document}

\begin{frame}[plain]
  \titlepage
\end{frame}

\begin{frame}{Überblick}
  \textbf{Was ist Go?}

  \textit{Go is an open source programming language that makes it easy to
  build simple, reliable, and efficient software.}\\[10mm]

  \url{https://golang.org}

  \begin{tikzpicture}[remember picture,overlay]
    \node[anchor=north east] at (current page.east)
      {\includegraphics[width=.7\textwidth]{gopher}};
  \end{tikzpicture}
\end{frame}

\begin{frame}{Web-Services}
  \begin{itemize}
      \item HTTP Frontend
	\begin{itemize}
	  \item Viele parallele Client-Anfragen
	  \item Eine oder mehrere Verbindungen zu Backends
	\end{itemize}
      \item Backend ("`Business Logic"')
	\begin{itemize}
	  \item Viele parallele Anfragen vom Frontend
	  \item Eine oder mehrere Datenbank-Verbindungen oder Interaktion mit
	    anderen Backends
	\end{itemize}
      \item Datenbank\\[3mm]

      \item[$\Rightarrow$] skalierbare Micro-Services~/ \textbf{lose
	Kopplung}\\[5mm]
  \end{itemize}

  \textbf{Auch:} Gleiche Prinzipien bei Integration mit anderen Lösungen
\end{frame}

\begin{frame}{Einschub: Go Standard Bibliothek}
  \url{https://golang.org/pkg/}\\[5mm]

  \begin{itemize}
    \item Crypto
    \item Datenbanken
    \item Go Parser
    \item Netzwerk, HTTP, SMTP, etc.
    \item Datenstrukturen\\[7mm]
  \end{itemize}

  \textbf{Mehr?} $\Rightarrow$ \url{https://godoc.org/}
\end{frame}

\begin{frame}[fragile]{Ein Webserver}
  \begin{lstlisting}
import (...)

func main() {
  http.HandleFunc("/hallo", sageHallo)
  log.Fatal(http.ListenAndServe(":9999", nil))
}

func sageHallo(w http.ResponseWriter, r *http.Request) {
  fmt.Fprintf(w, "Hallo %s", r.RemoteAddr)
}
\end{lstlisting}

  \begin{itemize}
    \item \url{https://golang.org/pkg/log/}
    \item \url{https://golang.org/pkg/net/http/}
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{Ein Webserver -- Templates}
  \begin{lstlisting}
var tmpl = template.Must(
  template.New("results").Parse(`
<html><head>
<title>{{.Title}}</title>
</head>

<body>
<h1>Hallo {{.Name}}</h1>
</body></html>
`))
  \end{lstlisting}

  \begin{itemize}
    \item \url{https://golang.org/pkg/html/template/}
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{Ein Webserver -- Templates (2)}
  \begin{lstlisting}
func sageHallo(...) {
  d := struct {
    Title, Name string
  }{"Hallo Welt", r.RemoteAddr}

  var buf bytes.Buffer
  if err := tmpl.Execute(&buf, d); err != nil {
    http.Error(w, err.Error(), http.StatusInternalServerError)
    return
  }
  io.Copy(w, &buf)
}
  \end{lstlisting}

  \begin{itemize}
    \item \url{https://golang.org/pkg/bytes/}
    \item \url{https://golang.org/pkg/io/}
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{Einschub: io.Writer}
  \begin{itemize}
    \item Warum funktioniert fmt.Printf, tmpl.Execute, http.Error, io.Copy
      eigentlich mit dem http.ResponseWriter und bytes.Buffer?
  \end{itemize}

  \begin{lstlisting}
package io
type Writer interface {
    Write(p []byte) (n int, err error)
}
  \end{lstlisting}

  \begin{itemize}
    \item[$\Rightarrow$] \textbf{Sehr} einfaches Interface
    \item[$\Rightarrow$] \texttt{http.ResponseWriter} und
      \texttt{bytes.Buffer} implementieren es\\[7mm]
  \end{itemize}

  Viele andere Beispiele ...
\end{frame}

\begin{frame}[fragile]{Viele Backend-Abfragen}
  \begin{lstlisting}
func Query(*Request) (*Response, error) { ... }

func anfrage(w http.ResponseWriter, r *http.Request) {
  requests := []*Request{...}

  responses := make([]*Reponse, len(requests))
  errCh := make(chan error, len(requests))

  for i, req := range requests {
    go func(i int, req *Request) {
      var err error
      responses[i], err = Query(req)
      errCh <- err
    }(i, req)
  }

  // ...
  \end{lstlisting}
\end{frame}

\begin{frame}[fragile]{Viele Backend-Abfragen (2)}
  \begin{lstlisting}
  ...
  timeout := time.After(50*time.Millisecond)

  for range requests {
    select {
    case err := <-errCh:
      if err != nil {
        http.Error(w, err.Error(), http.StatusBadRequest)
        return
      }
    case <-timeout:
      http.Error(w, "timeout", http.StatusRequestTimeout)
      return
    }
  }
  // Alle Ergebnisse verfügbar.
  \end{lstlisting}

  \begin{itemize}
    \item Siehe auch \url{https://golang.org/pkg/sync/#WaitGroup}
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{Spezielle Fehlerbehandlung}
  \begin{lstlisting}
  go func(req *Request) {
    var err error
    defer func() {
      if e := recover(); e != nil {
        err = fmt.Errorf("error while querying backend: %v", e)
      }
      errCh <- err
    }()

    responses[i], err = Query(req)
  }(req)
  \end{lstlisting}
\end{frame}

\begin{frame}{Backends -- gRPC}
  \textbf{Beispiel: Backend Kommunikation~/ API}\\[5mm]

  \textit{A high performance, open source, general RPC framework that puts
  mobile and HTTP/2 first.}\\[10mm]

  \url{https://grpc.io}\\
  \hfill\includegraphics[width=.3\textwidth]{grpc}
\end{frame}

\begin{frame}{gRPC Überblick}
  \url{https://github.com/google/protobuf}\\[5mm]

  \begin{itemize}
    \item gRPC basiert auf Protocol Buffers
    \item Unterstützung diverser Sprachen\newline
      C++, Java, Go, Python, \ldots
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{gRPC Beispiel}
  \begin{lstlisting}[morekeywords={syntax,service,message}]
syntax "proto3";

package mein_service;

service Backend {
  rpc Query(QueryRequest) return (QueryResponse);

  // ...
}

message QueryRequest {
  string query = 1;
}

message QueryResponse {
  string type = 1;
  int64 n = 2;
}
  \end{lstlisting}
\end{frame}

\begin{frame}{gRPC mit Go}
  \begin{itemize}
    \item Die "`protobuf"' Datei muss mittels des Protobuf Compilers und einer
      gRPC Compiler-Erweiterung übersetzt werden
    \item Der Compiler erzeugt Go Code, welcher Interfaces und generischen
      Code erzeugt
    \item Das Interface entspricht im Wesentlichen der \texttt{service}
      Definition
    \item Das Interface muss für den Server implementiert werden
    \item Generischer Client-Code sollte ausreichen\newline
      $\rightarrow$ API Entwurf!\\[7mm]
  \end{itemize}

  \url{https://github.com/grpc/grpc-go}\\
  \url{https://golang.org/x/net/context}
\end{frame}

\begin{frame}[fragile]{gRPC mit Go: Server}
  \begin{lstlisting}
import pb "tokkee.net/mein_service/service_proto"

type server struct{}

func (*server) Query(ctx context.Context,
  in *pb.QueryRequest) (*pb.QueryResponse, error) {

  n, err := runQuery(in.Query)
  if err != nil {
    return nil, err
  }
  return &pb.QueryResponse{
    Type: "irgendwas",
    N:    n,
  }, nil
}
  \end{lstlisting}
\end{frame}

\begin{frame}[fragile]{gRPC mit Go: Server (2)}
  \begin{lstlisting}
func main() {
  l, err := net.Listen("tcp", port)
  if err != nil {
    log.Fatal(err)
  }

  s := grpc.NewServer()
  pb.RegisterBackendServer(s, &server{})
  s.Serve(l)
}
  \end{lstlisting}
\end{frame}

\begin{frame}[fragile]{gRPC mit Go: Client}
  \begin{lstlisting}
func main() {
  ctx := context.Background()

  conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())
  if err != nil {
    log.Fatal(err)
  }
  defer conn.Close()
  c := pb.NewBackendClient(conn)

  res, err := c.Query(ctx, &pb.QueryRequest{
    Query: "ein query",
  })
  if err != nil {
    log.Fatal(err)
  }
  fmt.Printf("Antwort vom Typ %q: %d\n", res.Type, res.N)
}
  \end{lstlisting}
\end{frame}

\begin{frame}{\inserttitle}
  \begin{center}
    Danke für die Aufmerksamkeit\\[2mm]
    {\Large Fragen, Kommentare?}\\[6mm]

    \url{https://golang.org}\quad—\quad
    \url{https://github.com/grpc/grpc-go}
  \end{center}
\end{frame}

\end{document}

% vim: set shiftwidth=2 softtabstop=2 tabstop=8 noexpandtab spelllang=de_de :
