$30 off During Our Annual Pro Sale. View Details »

See Python, See Python Go, Go Python Go

See Python, See Python Go, Go Python Go

Talk given at PyCon 2016: https://us.pycon.org/2016/schedule/presentation/1633/

Being able to run C code from Python is pretty great, but what about running Go code from Python? Or even Python from Go? This talk will walk through the process of executing calls between Python and Go using CFFI bindings to bridge the two runtimes.
...

Andrey Petrov

June 01, 2016
Tweet

Other Decks in Programming

Transcript

  1. See Python, See Python Go, Go Python Go
    Presented by Andrey Petrov at PyCon 2016
    Andrey Petrov · @shazow

    View Slide

  2. Andrey Petrov
    @shazow
    urllib3, ssh-chat, briefmetrics, colorblendy, tweepsect, funny tweets, and more
    Andrey Petrov · @shazow

    View Slide

  3. Do you Go?
    Andrey Petrov · @shazow

    View Slide

  4. Do you Go?
    Simple syntax that is easy to learn
    Andrey Petrov · @shazow

    View Slide

  5. Do you Go?
    Simple syntax that is easy to learn
    Compiles superfast
    Andrey Petrov · @shazow

    View Slide

  6. Do you Go?
    Simple syntax that is easy to learn
    Compiles superfast
    Statically typed
    Andrey Petrov · @shazow

    View Slide

  7. Do you Go?
    Simple syntax that is easy to learn
    Compiles superfast
    Statically typed
    Statically linked binaries
    Andrey Petrov · @shazow

    View Slide

  8. Do you Go?
    Simple syntax that is easy to learn
    Compiles superfast
    Statically typed
    Statically linked binaries
    Cross-compiles to ~every platform
    Andrey Petrov · @shazow

    View Slide

  9. Do you Go?
    Simple syntax that is easy to learn
    Compiles superfast
    Statically typed
    Statically linked binaries
    Cross-compiles to ~every platform
    Easy concurrency
    Andrey Petrov · @shazow

    View Slide

  10. Do you Go?
    Simple syntax that is easy to learn
    Compiles superfast
    Statically typed
    Statically linked binaries
    Cross-compiles to ~every platform
    Easy concurrency
    Great standard library
    Andrey Petrov · @shazow

    View Slide

  11. Do you Go?
    Simple syntax that is easy to learn
    Compiles superfast
    Statically typed
    Statically linked binaries
    Cross-compiles to ~every platform
    Easy concurrency
    Great standard library
    Gophers!
    Andrey Petrov · @shazow

    View Slide

  12. Python Go
    Andrey Petrov · @shazow
    Credit: Renee French & Alice Tribuleva

    View Slide

  13. Go in Python
    i
    m
    p
    o
    r
    t o
    s
    o
    s
    .
    s
    y
    s
    t
    e
    m
    (
    "
    g
    o r
    u
    n m
    a
    i
    n
    .
    g
    o
    "
    )
    Andrey Petrov · @shazow

    View Slide

  14. Go in Python
    i
    m
    p
    o
    r
    t o
    s
    o
    s
    .
    s
    y
    s
    t
    e
    m
    (
    "
    g
    o r
    u
    n m
    a
    i
    n
    .
    g
    o
    "
    )
    lol just kidding
    Andrey Petrov · @shazow

    View Slide

  15. Fun Facts
    Python speaks with C
    Andrey Petrov · @shazow

    View Slide

  16. Fun Facts
    Python speaks with C
    Go speaks with C
    Andrey Petrov · @shazow

    View Slide

  17. Fun Facts
    Python speaks with C
    Go speaks with C
    Therefore, Python speaks with Go?
    Andrey Petrov · @shazow

    View Slide

  18. Challenges
    1. Runtime barriers
    Andrey Petrov · @shazow

    View Slide

  19. Challenges
    1. Runtime barriers
    Garbage Collectors (GC)
    Global Interpreter Lock (GIL)
    Just In Time compiling (JIT)
    Resource Pools (Threads)
    Andrey Petrov · @shazow

    View Slide

  20. Challenges
    1. Runtime barriers
    Garbage Collectors (GC)
    Global Interpreter Lock (GIL)
    Just In Time compiling (JIT)
    Resource Pools (Threads)
    2. Syntax and feature barriers
    Andrey Petrov · @shazow

    View Slide

  21. Challenges
    1. Runtime barriers
    Garbage Collectors (GC)
    Global Interpreter Lock (GIL)
    Just In Time compiling (JIT)
    Resource Pools (Threads)
    2. Syntax and feature barriers
    Go: Interface, Goroutines, etc.
    Python: Classes, Generators, etc.
    Oodles of other language-specific constructs
    Andrey Petrov · @shazow

    View Slide

  22. Go
    runtime
    Python
    runtime
    C GIL
    GC
    Interpreter
    Ponies
    GC
    Goroutines
    Gophers
    Andrey Petrov · @shazow

    View Slide

  23. Let's take a moment and imagine...
    Andrey Petrov · @shazow

    View Slide

  24. Running a webserver in Go
    p
    a
    c
    k
    a
    g
    e m
    a
    i
    n
    i
    m
    p
    o
    r
    t (
    "
    f
    m
    t
    "
    "
    n
    e
    t
    /
    h
    t
    t
    p
    "
    )
    f
    u
    n
    c i
    n
    d
    e
    x
    (
    w h
    t
    t
    p
    .
    R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    , r
    e
    q *
    h
    t
    t
    p
    .
    R
    e
    q
    u
    e
    s
    t
    ) {
    f
    m
    t
    .
    F
    p
    r
    i
    n
    t
    f
    (
    w
    , "
    H
    e
    l
    l
    o
    , w
    o
    r
    l
    d
    .
    \
    n
    "
    )
    }
    f
    u
    n
    c m
    a
    i
    n
    (
    ) {
    h
    t
    t
    p
    .
    H
    a
    n
    d
    l
    e
    F
    u
    n
    c
    (
    "
    /
    "
    , i
    n
    d
    e
    x
    )
    h
    t
    t
    p
    .
    L
    i
    s
    t
    e
    n
    A
    n
    d
    S
    e
    r
    v
    e
    (
    "
    1
    2
    7
    .
    0
    .
    0
    .
    1
    :
    5
    0
    0
    0
    "
    , n
    i
    l
    )
    }
    Andrey Petrov · @shazow

    View Slide

  25. Running a webserver in Python
    f
    r
    o
    m f
    l
    a
    s
    k i
    m
    p
    o
    r
    t F
    l
    a
    s
    k
    a
    p
    p = F
    l
    a
    s
    k
    (
    _
    _
    n
    a
    m
    e
    _
    _
    )
    @
    a
    p
    p
    .
    r
    o
    u
    t
    e
    (
    '
    /
    '
    )
    d
    e
    f i
    n
    d
    e
    x
    (
    )
    :
    r
    e
    t
    u
    r
    n '
    H
    e
    l
    l
    o
    , w
    o
    r
    l
    d
    !
    \
    n
    '
    i
    f _
    _
    n
    a
    m
    e
    _
    _ =
    = '
    _
    _
    m
    a
    i
    n
    _
    _
    '
    :
    a
    p
    p
    .
    r
    u
    n
    (
    h
    o
    s
    t
    =
    '
    1
    2
    7
    .
    0
    .
    0
    .
    1
    '
    , p
    o
    r
    t
    =
    5
    0
    0
    0
    )
    Andrey Petrov · @shazow

    View Slide

  26. Running a Go webserver in Python??
    f
    r
    o
    m g
    o
    h
    t
    t
    p i
    m
    p
    o
    r
    t r
    o
    u
    t
    e
    , r
    u
    n
    @
    r
    o
    u
    t
    e
    (
    '
    /
    '
    )
    d
    e
    f i
    n
    d
    e
    x
    (
    w
    , r
    e
    q
    )
    :
    w
    .
    w
    r
    i
    t
    e
    (
    "
    H
    e
    l
    l
    o
    , w
    o
    r
    l
    d
    .
    \
    n
    "
    )
    i
    f _
    _
    n
    a
    m
    e
    _
    _ =
    = '
    _
    _
    m
    a
    i
    n
    _
    _
    '
    :
    r
    u
    n
    (
    h
    o
    s
    t
    =
    '
    1
    2
    7
    .
    0
    .
    0
    .
    1
    '
    , p
    o
    r
    t
    =
    5
    0
    0
    0
    )
    Andrey Petrov · @shazow

    View Slide

  27. Running a Go webserver in Python??
    f
    r
    o
    m g
    o
    h
    t
    t
    p i
    m
    p
    o
    r
    t r
    o
    u
    t
    e
    , r
    u
    n
    @
    r
    o
    u
    t
    e
    (
    '
    /
    '
    )
    d
    e
    f i
    n
    d
    e
    x
    (
    w
    , r
    e
    q
    )
    :
    w
    .
    w
    r
    i
    t
    e
    (
    "
    H
    e
    l
    l
    o
    , w
    o
    r
    l
    d
    .
    \
    n
    "
    )
    i
    f _
    _
    n
    a
    m
    e
    _
    _ =
    = '
    _
    _
    m
    a
    i
    n
    _
    _
    '
    :
    r
    u
    n
    (
    h
    o
    s
    t
    =
    '
    1
    2
    7
    .
    0
    .
    0
    .
    1
    '
    , p
    o
    r
    t
    =
    5
    0
    0
    0
    )
    Compare
    f
    r
    o
    m f
    l
    a
    s
    k i
    m
    p
    o
    r
    t F
    l
    a
    s
    k
    a
    p
    p = F
    l
    a
    s
    k
    (
    _
    _
    n
    a
    m
    e
    _
    _
    )
    @
    a
    p
    p
    .
    r
    o
    u
    t
    e
    (
    '
    /
    '
    )
    d
    e
    f i
    n
    d
    e
    x
    (
    )
    :
    r
    e
    t
    u
    r
    n '
    H
    e
    l
    l
    o
    , w
    o
    r
    l
    d
    !
    \
    n
    '
    i
    f _
    _
    n
    a
    m
    e
    _
    _ =
    = '
    _
    _
    m
    a
    i
    n
    _
    _
    '
    :
    a
    p
    p
    .
    r
    u
    n
    (
    h
    o
    s
    t
    =
    '
    1
    2
    7
    .
    0
    .
    0
    .
    1
    '
    , p
    o
    r
    t
    =
    5
    0
    0
    0
    )
    Andrey Petrov · @shazow

    View Slide

  28. Comparing handlers
    Go (net/http)
    f
    u
    n
    c i
    n
    d
    e
    x
    (
    w h
    t
    t
    p
    .
    R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    , r
    e
    q *
    h
    t
    t
    p
    .
    R
    e
    q
    u
    e
    s
    t
    ) {
    f
    m
    t
    .
    F
    p
    r
    i
    n
    t
    f
    (
    w
    , "
    H
    e
    l
    l
    o
    , w
    o
    r
    l
    d
    .
    \
    n
    "
    )
    }
    Go in Python (gohttplib)
    d
    e
    f i
    n
    d
    e
    x
    (
    w
    , r
    e
    q
    )
    :
    w
    .
    w
    r
    i
    t
    e
    (
    "
    H
    e
    l
    l
    o
    , w
    o
    r
    l
    d
    .
    \
    n
    "
    )
    Python (flask)
    d
    e
    f i
    n
    d
    e
    x
    (
    )
    :
    r
    e
    t
    u
    r
    n '
    H
    e
    l
    l
    o
    , w
    o
    r
    l
    d
    !
    \
    n
    '
    Andrey Petrov · @shazow

    View Slide

  29. gohttplib
    This is an actual functioning thing.
    github.com/shazow/gohttplib
    Andrey Petrov · @shazow

    View Slide

  30. gohttplib
    This is an actual functioning thing.
    github.com/shazow/gohttplib
    Sponsored by Glider Labs
    Andrey Petrov · @shazow

    View Slide

  31. Here's how it works...
    Andrey Petrov · @shazow

    View Slide

  32. The Plan
    1. Go: Export Go functions to a C shared library
    2. C:
    3. Python: Call C and wrap it in a Python-shaped bow
    4. Make it actually work ¯\_(ツ)_/¯
    Andrey Petrov · @shazow

    View Slide

  33. Andrey Petrov · @shazow

    View Slide

  34. Calling C from Go
    p
    a
    c
    k
    a
    g
    e m
    a
    i
    n
    /
    *
    i
    n
    t t
    h
    e
    _
    a
    n
    s
    w
    e
    r
    (
    ) {
    r
    e
    t
    u
    r
    n 4
    2
    ;
    }
    *
    /
    i
    m
    p
    o
    r
    t "
    C
    "
    i
    m
    p
    o
    r
    t "
    f
    m
    t
    "
    f
    u
    n
    c m
    a
    i
    n
    (
    ) {
    r :
    = C
    .
    t
    h
    e
    _
    a
    n
    s
    w
    e
    r
    (
    )
    f
    m
    t
    .
    P
    r
    i
    n
    t
    l
    n
    (
    r
    )
    }
    Andrey Petrov · @shazow

    View Slide

  35. Calling C from Go
    p
    a
    c
    k
    a
    g
    e m
    a
    i
    n
    /
    *
    i
    n
    t t
    h
    e
    _
    a
    n
    s
    w
    e
    r
    (
    ) {
    r
    e
    t
    u
    r
    n 4
    2
    ;
    }
    *
    /
    i
    m
    p
    o
    r
    t "
    C
    "
    i
    m
    p
    o
    r
    t "
    f
    m
    t
    "
    f
    u
    n
    c m
    a
    i
    n
    (
    ) {
    r :
    = C
    .
    t
    h
    e
    _
    a
    n
    s
    w
    e
    r
    (
    )
    f
    m
    t
    .
    P
    r
    i
    n
    t
    l
    n
    (
    r
    )
    }
    $ g
    o b
    u
    i
    l
    d -
    o a
    n
    s
    w
    e
    r
    $ .
    /
    a
    n
    s
    w
    e
    r
    4
    2
    Andrey Petrov · @shazow

    View Slide

  36. Calling Go from C
    p
    a
    c
    k
    a
    g
    e m
    a
    i
    n
    i
    m
    p
    o
    r
    t "
    C
    "
    /
    /
    e
    x
    p
    o
    r
    t T
    h
    e
    A
    n
    s
    w
    e
    r
    f
    u
    n
    c T
    h
    e
    A
    n
    s
    w
    e
    r
    (
    ) C
    .
    i
    n
    t {
    r
    e
    t
    u
    r
    n C
    .
    i
    n
    t
    (
    4
    2
    )
    }
    f
    u
    n
    c m
    a
    i
    n
    (
    ) {
    }
    Andrey Petrov · @shazow

    View Slide

  37. Calling Go from C
    p
    a
    c
    k
    a
    g
    e m
    a
    i
    n
    i
    m
    p
    o
    r
    t "
    C
    "
    /
    /
    e
    x
    p
    o
    r
    t T
    h
    e
    A
    n
    s
    w
    e
    r
    f
    u
    n
    c T
    h
    e
    A
    n
    s
    w
    e
    r
    (
    ) C
    .
    i
    n
    t {
    r
    e
    t
    u
    r
    n C
    .
    i
    n
    t
    (
    4
    2
    )
    }
    f
    u
    n
    c m
    a
    i
    n
    (
    ) {
    }
    $ g
    o b
    u
    i
    l
    d -
    b
    u
    i
    l
    d
    m
    o
    d
    e
    =
    c
    -
    s
    h
    a
    r
    e
    d -
    o l
    i
    b
    a
    n
    s
    w
    e
    r
    .
    s
    o
    Andrey Petrov · @shazow

    View Slide

  38. Calling Go from C
    p
    a
    c
    k
    a
    g
    e m
    a
    i
    n
    i
    m
    p
    o
    r
    t "
    C
    "
    /
    /
    e
    x
    p
    o
    r
    t T
    h
    e
    A
    n
    s
    w
    e
    r
    f
    u
    n
    c T
    h
    e
    A
    n
    s
    w
    e
    r
    (
    ) C
    .
    i
    n
    t {
    r
    e
    t
    u
    r
    n C
    .
    i
    n
    t
    (
    4
    2
    )
    }
    f
    u
    n
    c m
    a
    i
    n
    (
    ) {
    }
    $ g
    o b
    u
    i
    l
    d -
    b
    u
    i
    l
    d
    m
    o
    d
    e
    =
    c
    -
    s
    h
    a
    r
    e
    d -
    o l
    i
    b
    a
    n
    s
    w
    e
    r
    .
    s
    o
    #
    i
    n
    c
    l
    u
    d
    e <
    s
    t
    d
    i
    o
    .
    h
    >
    #
    i
    n
    c
    l
    u
    d
    e "
    l
    i
    b
    a
    n
    s
    w
    e
    r
    .
    h
    "
    i
    n
    t m
    a
    i
    n
    (
    ) {
    i
    n
    t r = T
    h
    e
    A
    n
    s
    w
    e
    r
    (
    )
    ;
    p
    r
    i
    n
    t
    f
    (
    "
    %
    d
    \
    n
    "
    , r
    )
    ;
    r
    e
    t
    u
    r
    n 0
    ;
    }
    Andrey Petrov · @shazow

    View Slide

  39. Andrey Petrov · @shazow

    View Slide

  40. See CPython C
    CPython Extension Interface: no dependencies, but
    lots of boilerplate
    CFFI: a little more magic but does more work for us
    and more portable
    Andrey Petrov · @shazow

    View Slide

  41. Calling C from Python
    # a
    n
    s
    w
    e
    r
    _
    b
    u
    i
    l
    d
    .
    p
    y
    :
    f
    r
    o
    m c
    f
    f
    i i
    m
    p
    o
    r
    t F
    F
    I
    f
    f
    i = F
    F
    I
    (
    )
    f
    f
    i
    .
    c
    d
    e
    f
    (
    "
    i
    n
    t t
    h
    e
    _
    a
    n
    s
    w
    e
    r
    (
    )
    ;
    "
    )
    f
    f
    i
    .
    s
    e
    t
    _
    s
    o
    u
    r
    c
    e
    (
    "
    _
    a
    n
    s
    w
    e
    r
    "
    , "
    "
    "
    i
    n
    t t
    h
    e
    _
    a
    n
    s
    w
    e
    r
    (
    ) {
    r
    e
    t
    u
    r
    n 4
    2
    ;
    }
    "
    "
    "
    )
    i
    f _
    _
    n
    a
    m
    e
    _
    _ =
    = "
    _
    _
    m
    a
    i
    n
    _
    _
    "
    :
    f
    f
    i
    .
    c
    o
    m
    p
    i
    l
    e
    (
    )
    Andrey Petrov · @shazow

    View Slide

  42. Calling C from Python
    # a
    n
    s
    w
    e
    r
    _
    b
    u
    i
    l
    d
    .
    p
    y
    :
    f
    r
    o
    m c
    f
    f
    i i
    m
    p
    o
    r
    t F
    F
    I
    f
    f
    i = F
    F
    I
    (
    )
    f
    f
    i
    .
    c
    d
    e
    f
    (
    "
    i
    n
    t t
    h
    e
    _
    a
    n
    s
    w
    e
    r
    (
    )
    ;
    "
    )
    f
    f
    i
    .
    s
    e
    t
    _
    s
    o
    u
    r
    c
    e
    (
    "
    _
    a
    n
    s
    w
    e
    r
    "
    , "
    "
    "
    i
    n
    t t
    h
    e
    _
    a
    n
    s
    w
    e
    r
    (
    ) {
    r
    e
    t
    u
    r
    n 4
    2
    ;
    }
    "
    "
    "
    )
    i
    f _
    _
    n
    a
    m
    e
    _
    _ =
    = "
    _
    _
    m
    a
    i
    n
    _
    _
    "
    :
    f
    f
    i
    .
    c
    o
    m
    p
    i
    l
    e
    (
    )
    $ p
    y
    t
    h
    o
    n a
    n
    s
    w
    e
    r
    _
    b
    u
    i
    l
    d
    .
    p
    y
    $ l
    s
    _
    a
    n
    s
    w
    e
    r
    .
    c _
    a
    n
    s
    w
    e
    r
    .
    o _
    a
    n
    s
    w
    e
    r
    .
    s
    o a
    n
    s
    w
    e
    r
    _
    b
    u
    i
    l
    d
    .
    p
    y
    Andrey Petrov · @shazow

    View Slide

  43. Calling C from Python
    # a
    n
    s
    w
    e
    r
    _
    b
    u
    i
    l
    d
    .
    p
    y
    :
    f
    r
    o
    m c
    f
    f
    i i
    m
    p
    o
    r
    t F
    F
    I
    f
    f
    i = F
    F
    I
    (
    )
    f
    f
    i
    .
    c
    d
    e
    f
    (
    "
    i
    n
    t t
    h
    e
    _
    a
    n
    s
    w
    e
    r
    (
    )
    ;
    "
    )
    f
    f
    i
    .
    s
    e
    t
    _
    s
    o
    u
    r
    c
    e
    (
    "
    _
    a
    n
    s
    w
    e
    r
    "
    , "
    "
    "
    i
    n
    t t
    h
    e
    _
    a
    n
    s
    w
    e
    r
    (
    ) {
    r
    e
    t
    u
    r
    n 4
    2
    ;
    }
    "
    "
    "
    )
    i
    f _
    _
    n
    a
    m
    e
    _
    _ =
    = "
    _
    _
    m
    a
    i
    n
    _
    _
    "
    :
    f
    f
    i
    .
    c
    o
    m
    p
    i
    l
    e
    (
    )
    $ p
    y
    t
    h
    o
    n a
    n
    s
    w
    e
    r
    _
    b
    u
    i
    l
    d
    .
    p
    y
    $ l
    s
    _
    a
    n
    s
    w
    e
    r
    .
    c _
    a
    n
    s
    w
    e
    r
    .
    o _
    a
    n
    s
    w
    e
    r
    .
    s
    o a
    n
    s
    w
    e
    r
    _
    b
    u
    i
    l
    d
    .
    p
    y
    # a
    n
    s
    w
    e
    r
    .
    p
    y
    :
    f
    r
    o
    m _
    a
    n
    s
    w
    e
    r i
    m
    p
    o
    r
    t l
    i
    b
    p
    r
    i
    n
    t
    (
    l
    i
    b
    .
    t
    h
    e
    _
    a
    n
    s
    w
    e
    r
    (
    )
    )
    Andrey Petrov · @shazow

    View Slide

  44. Calling Python from C
    Simple function pointer that can be used in C:
    @
    f
    f
    i
    .
    c
    a
    l
    l
    b
    a
    c
    k
    (
    "
    i
    n
    t
    (
    i
    n
    t
    , i
    n
    t
    )
    "
    )
    d
    e
    f a
    d
    d
    (
    x
    , y
    )
    :
    r
    e
    t
    u
    r
    n x + y
    Andrey Petrov · @shazow

    View Slide

  45. Calling Python from C
    Simple function pointer that can be used in C:
    @
    f
    f
    i
    .
    c
    a
    l
    l
    b
    a
    c
    k
    (
    "
    i
    n
    t
    (
    i
    n
    t
    , i
    n
    t
    )
    "
    )
    d
    e
    f a
    d
    d
    (
    x
    , y
    )
    :
    r
    e
    t
    u
    r
    n x + y
    ~handwaving~
    Andrey Petrov · @shazow

    View Slide

  46. Calling Python from C
    Simple function pointer that can be used in C:
    @
    f
    f
    i
    .
    c
    a
    l
    l
    b
    a
    c
    k
    (
    "
    i
    n
    t
    (
    i
    n
    t
    , i
    n
    t
    )
    "
    )
    d
    e
    f a
    d
    d
    (
    x
    , y
    )
    :
    r
    e
    t
    u
    r
    n x + y
    ~handwaving~
    s
    t
    a
    t
    i
    c i
    n
    t (
    *
    a
    d
    d
    )
    (
    i
    n
    t x
    , i
    n
    t b
    )
    ;
    That's all we need for now. More on CFFI embedding here.
    Andrey Petrov · @shazow

    View Slide

  47. Challenges
    1. Runtime barriers
    Garbage Collectors (GC)
    Global Interpreter Lock (GIL)
    Just In Time compiling in PyPy (JIT)
    Thread Pools
    2. Syntax and feature barriers
    Go: Interface, Goroutines, etc.
    Python: Classes, Generators, etc.
    Oodles of other language-specific constructs
    Andrey Petrov · @shazow

    View Slide

  48. Overcoming Challenges
    1. Don't share memory
    Andrey Petrov · @shazow

    View Slide

  49. Go
    runtime
    Python
    runtime
    C GIL
    GC
    Interpreter
    Ponies
    GC
    Goroutines
    Gophers
    Andrey Petrov · @shazow

    View Slide

  50. Challenge 1: Don't share memory
    h
    t
    t
    p
    .
    H
    a
    n
    d
    l
    e
    F
    u
    n
    c
    (
    p
    a
    t
    t
    e
    r
    n
    , f
    u
    n
    c
    (
    w h
    t
    t
    p
    .
    R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    , r
    e
    q *
    h
    t
    t
    p
    .
    R
    e
    q
    u
    e
    s
    t
    ) {
    .
    .
    .
    }
    )
    Our Python code will need to provide this callback, but we can't pass
    *
    h
    t
    t
    p
    .
    R
    e
    q
    u
    e
    s
    t
    to Python.
    Andrey Petrov · @shazow

    View Slide

  51. Challenge 1: Don't share memory
    h
    t
    t
    p
    .
    H
    a
    n
    d
    l
    e
    F
    u
    n
    c
    (
    p
    a
    t
    t
    e
    r
    n
    , f
    u
    n
    c
    (
    w h
    t
    t
    p
    .
    R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    , r
    e
    q *
    h
    t
    t
    p
    .
    R
    e
    q
    u
    e
    s
    t
    ) {
    .
    .
    .
    }
    )
    Our Python code will need to provide this callback, but we can't pass
    *
    h
    t
    t
    p
    .
    R
    e
    q
    u
    e
    s
    t
    to Python.
    t
    y
    p
    e
    d
    e
    f s
    t
    r
    u
    c
    t R
    e
    q
    u
    e
    s
    t
    _
    {
    c
    o
    n
    s
    t c
    h
    a
    r *
    M
    e
    t
    h
    o
    d
    ;
    c
    o
    n
    s
    t c
    h
    a
    r *
    H
    o
    s
    t
    ;
    .
    .
    .
    } R
    e
    q
    u
    e
    s
    t
    ;
    Andrey Petrov · @shazow

    View Slide

  52. Challenge 1: Don't share memory
    h
    t
    t
    p
    .
    H
    a
    n
    d
    l
    e
    F
    u
    n
    c
    (
    p
    a
    t
    t
    e
    r
    n
    , f
    u
    n
    c
    (
    w h
    t
    t
    p
    .
    R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    , r
    e
    q *
    h
    t
    t
    p
    .
    R
    e
    q
    u
    e
    s
    t
    ) {
    .
    .
    .
    }
    )
    Our Python code will need to provide this callback, but we can't pass
    *
    h
    t
    t
    p
    .
    R
    e
    q
    u
    e
    s
    t
    to Python.
    t
    y
    p
    e
    d
    e
    f s
    t
    r
    u
    c
    t R
    e
    q
    u
    e
    s
    t
    _
    {
    c
    o
    n
    s
    t c
    h
    a
    r *
    M
    e
    t
    h
    o
    d
    ;
    c
    o
    n
    s
    t c
    h
    a
    r *
    H
    o
    s
    t
    ;
    .
    .
    .
    } R
    e
    q
    u
    e
    s
    t
    ;
    h
    t
    t
    p
    .
    H
    a
    n
    d
    l
    e
    F
    u
    n
    c
    (
    p
    a
    t
    t
    e
    r
    n
    , f
    u
    n
    c
    (
    w h
    t
    t
    p
    .
    R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    , r
    e
    q *
    h
    t
    t
    p
    .
    R
    e
    q
    u
    e
    s
    t
    ) {
    /
    / W
    r
    a
    p r
    e
    l
    e
    v
    a
    n
    t r
    e
    q
    u
    e
    s
    t f
    i
    e
    l
    d
    s i
    n a C
    -
    f
    r
    i
    e
    n
    d
    l
    y d
    a
    t
    a
    s
    t
    r
    u
    c
    t
    u
    r
    e
    .
    c
    r
    e
    q :
    = C
    .
    R
    e
    q
    u
    e
    s
    t
    {
    M
    e
    t
    h
    o
    d
    : C
    .
    C
    S
    t
    r
    i
    n
    g
    (
    r
    e
    q
    .
    M
    e
    t
    h
    o
    d
    )
    ,
    H
    o
    s
    t
    : C
    .
    C
    S
    t
    r
    i
    n
    g
    (
    r
    e
    q
    .
    H
    o
    s
    t
    )
    ,
    .
    .
    .
    }
    .
    .
    .
    Andrey Petrov · @shazow

    View Slide

  53. Overcoming Challenges
    1. Don't share memory
    2. Translation layer
    Andrey Petrov · @shazow

    View Slide

  54. Challenge 2: Translation layer
    h
    t
    t
    p
    .
    H
    a
    n
    d
    l
    e
    F
    u
    n
    c
    (
    p
    a
    t
    t
    e
    r
    n
    , f
    u
    n
    c
    (
    w h
    t
    t
    p
    .
    R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    , r
    e
    q *
    h
    t
    t
    p
    .
    R
    e
    q
    u
    e
    s
    t
    ) {
    .
    .
    .
    }
    )
    Our Python code will need to use the h
    t
    t
    p
    .
    R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    interface.
    Andrey Petrov · @shazow

    View Slide

  55. Challenge 2: Translation layer
    h
    t
    t
    p
    .
    H
    a
    n
    d
    l
    e
    F
    u
    n
    c
    (
    p
    a
    t
    t
    e
    r
    n
    , f
    u
    n
    c
    (
    w h
    t
    t
    p
    .
    R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    , r
    e
    q *
    h
    t
    t
    p
    .
    R
    e
    q
    u
    e
    s
    t
    ) {
    .
    .
    .
    }
    )
    Our Python code will need to use the h
    t
    t
    p
    .
    R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    interface.
    R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    .
    W
    r
    i
    t
    e
    (
    [
    ]
    b
    y
    t
    e
    ) (
    i
    n
    t
    , e
    r
    r
    o
    r
    )
    R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    .
    W
    r
    i
    t
    e
    H
    e
    a
    d
    e
    r
    (
    i
    n
    t
    )
    Andrey Petrov · @shazow

    View Slide

  56. Challenge 2: Translation layer
    h
    t
    t
    p
    .
    H
    a
    n
    d
    l
    e
    F
    u
    n
    c
    (
    p
    a
    t
    t
    e
    r
    n
    , f
    u
    n
    c
    (
    w h
    t
    t
    p
    .
    R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    , r
    e
    q *
    h
    t
    t
    p
    .
    R
    e
    q
    u
    e
    s
    t
    ) {
    .
    .
    .
    }
    )
    Our Python code will need to use the h
    t
    t
    p
    .
    R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    interface.
    R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    .
    W
    r
    i
    t
    e
    (
    [
    ]
    b
    y
    t
    e
    ) (
    i
    n
    t
    , e
    r
    r
    o
    r
    )
    R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    .
    W
    r
    i
    t
    e
    H
    e
    a
    d
    e
    r
    (
    i
    n
    t
    )
    /
    /
    e
    x
    p
    o
    r
    t R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    _
    W
    r
    i
    t
    e
    f
    u
    n
    c R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    _
    W
    r
    i
    t
    e
    (
    w
    P
    t
    r C
    .
    u
    i
    n
    t
    , c
    b
    u
    f *
    C
    .
    c
    h
    a
    r
    , l
    e
    n
    g
    t
    h C
    .
    i
    n
    t
    ) C
    .
    i
    n
    t {
    b
    u
    f :
    = C
    .
    G
    o
    B
    y
    t
    e
    s
    (
    u
    n
    s
    a
    f
    e
    .
    P
    o
    i
    n
    t
    e
    r
    (
    c
    b
    u
    f
    )
    , l
    e
    n
    g
    t
    h
    )
    .
    .
    .
    n
    , _ :
    = (
    *
    (
    *
    h
    t
    t
    p
    .
    R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    )
    (
    w
    )
    )
    .
    W
    r
    i
    t
    e
    (
    b
    u
    f
    )
    r
    e
    t
    u
    r
    n C
    .
    i
    n
    t
    (
    n
    )
    }
    /
    /
    e
    x
    p
    o
    r
    t R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    _
    W
    r
    i
    t
    e
    H
    e
    a
    d
    e
    r
    f
    u
    n
    c R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    _
    W
    r
    i
    t
    e
    H
    e
    a
    d
    e
    r
    (
    w
    P
    t
    r C
    .
    u
    i
    n
    t
    , h
    e
    a
    d
    e
    r C
    .
    i
    n
    t
    ) {
    .
    .
    .
    (
    *
    (
    *
    h
    t
    t
    p
    .
    R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    )
    (
    w
    )
    )
    .
    W
    r
    i
    t
    e
    H
    e
    a
    d
    e
    r
    (
    i
    n
    t
    (
    h
    e
    a
    d
    e
    r
    )
    )
    }
    Andrey Petrov · @shazow

    View Slide

  57. Challenge 2: Translation layer (Cont.)
    We exported these functions in Go
    R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    _
    W
    r
    i
    t
    e
    (
    w
    P
    t
    r C
    .
    u
    i
    n
    t
    , c
    b
    u
    f *
    C
    .
    c
    h
    a
    r
    , l
    e
    n
    g
    t
    h C
    .
    i
    n
    t
    ) C
    .
    i
    n
    t
    R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    _
    W
    r
    i
    t
    e
    H
    e
    a
    d
    e
    r
    (
    w
    P
    t
    r C
    .
    u
    i
    n
    t
    , h
    e
    a
    d
    e
    r C
    .
    i
    n
    t
    )
    Now we can wrap them in Python
    l
    i
    b = f
    f
    i
    .
    d
    l
    o
    p
    e
    n
    (
    .
    .
    .
    )
    c
    l
    a
    s
    s R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    :
    d
    e
    f _
    _
    i
    n
    i
    t
    _
    _
    (
    s
    e
    l
    f
    , w
    )
    :
    s
    e
    l
    f
    .
    _
    w = w
    d
    e
    f w
    r
    i
    t
    e
    (
    s
    e
    l
    f
    , b
    o
    d
    y
    )
    :
    n = l
    i
    b
    .
    R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    _
    W
    r
    i
    t
    e
    (
    s
    e
    l
    f
    .
    _
    w
    , b
    o
    d
    y
    , l
    e
    n
    (
    b
    o
    d
    y
    )
    )
    i
    f n !
    = l
    e
    n
    (
    b
    o
    d
    y
    )
    :
    r
    a
    i
    s
    e I
    O
    E
    r
    r
    o
    r
    (
    "
    F
    a
    i
    l
    e
    d t
    o w
    r
    i
    t
    e t
    o R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    .
    "
    )
    d
    e
    f s
    e
    t
    _
    s
    t
    a
    t
    u
    s
    (
    s
    e
    l
    f
    , c
    o
    d
    e
    )
    :
    l
    i
    b
    .
    R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    _
    W
    r
    i
    t
    e
    H
    e
    a
    d
    e
    r
    (
    s
    e
    l
    f
    .
    _
    w
    , c
    o
    d
    e
    )
    Andrey Petrov · @shazow

    View Slide

  58. Challenge 2: Translation layer (Cont.)
    Original interface in Go:
    t
    y
    p
    e h
    t
    t
    p
    .
    R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r i
    n
    t
    e
    r
    f
    a
    c
    e { W
    r
    i
    t
    e
    H
    e
    a
    d
    e
    r
    (
    i
    n
    t
    ) }
    Andrey Petrov · @shazow

    View Slide

  59. Challenge 2: Translation layer (Cont.)
    Original interface in Go:
    t
    y
    p
    e h
    t
    t
    p
    .
    R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r i
    n
    t
    e
    r
    f
    a
    c
    e { W
    r
    i
    t
    e
    H
    e
    a
    d
    e
    r
    (
    i
    n
    t
    ) }
    Exported interface from Go:
    f
    u
    n
    c R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    _
    W
    r
    i
    t
    e
    H
    e
    a
    d
    e
    r
    (
    w
    P
    t
    r C
    .
    u
    i
    n
    t
    , h
    e
    a
    d
    e
    r C
    .
    i
    n
    t
    )
    Andrey Petrov · @shazow

    View Slide

  60. Challenge 2: Translation layer (Cont.)
    Original interface in Go:
    t
    y
    p
    e h
    t
    t
    p
    .
    R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r i
    n
    t
    e
    r
    f
    a
    c
    e { W
    r
    i
    t
    e
    H
    e
    a
    d
    e
    r
    (
    i
    n
    t
    ) }
    Exported interface from Go:
    f
    u
    n
    c R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    _
    W
    r
    i
    t
    e
    H
    e
    a
    d
    e
    r
    (
    w
    P
    t
    r C
    .
    u
    i
    n
    t
    , h
    e
    a
    d
    e
    r C
    .
    i
    n
    t
    )
    C header:
    v
    o
    i
    d R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    _
    W
    r
    i
    t
    e
    H
    e
    a
    d
    e
    r
    (
    u
    n
    s
    i
    g
    n
    e
    d i
    n
    t p
    0
    , i
    n
    t p
    1
    )
    ;
    Andrey Petrov · @shazow

    View Slide

  61. Challenge 2: Translation layer (Cont.)
    Original interface in Go:
    t
    y
    p
    e h
    t
    t
    p
    .
    R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r i
    n
    t
    e
    r
    f
    a
    c
    e { W
    r
    i
    t
    e
    H
    e
    a
    d
    e
    r
    (
    i
    n
    t
    ) }
    Exported interface from Go:
    f
    u
    n
    c R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    _
    W
    r
    i
    t
    e
    H
    e
    a
    d
    e
    r
    (
    w
    P
    t
    r C
    .
    u
    i
    n
    t
    , h
    e
    a
    d
    e
    r C
    .
    i
    n
    t
    )
    C header:
    v
    o
    i
    d R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    _
    W
    r
    i
    t
    e
    H
    e
    a
    d
    e
    r
    (
    u
    n
    s
    i
    g
    n
    e
    d i
    n
    t p
    0
    , i
    n
    t p
    1
    )
    ;
    Accessing C from Python:
    R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    _
    W
    r
    i
    t
    e
    H
    e
    a
    d
    e
    r
    (
    w
    , h
    e
    a
    d
    e
    r
    )
    Andrey Petrov · @shazow

    View Slide

  62. Challenge 2: Translation layer (Cont.)
    Original interface in Go:
    t
    y
    p
    e h
    t
    t
    p
    .
    R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r i
    n
    t
    e
    r
    f
    a
    c
    e { W
    r
    i
    t
    e
    H
    e
    a
    d
    e
    r
    (
    i
    n
    t
    ) }
    Exported interface from Go:
    f
    u
    n
    c R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    _
    W
    r
    i
    t
    e
    H
    e
    a
    d
    e
    r
    (
    w
    P
    t
    r C
    .
    u
    i
    n
    t
    , h
    e
    a
    d
    e
    r C
    .
    i
    n
    t
    )
    C header:
    v
    o
    i
    d R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    _
    W
    r
    i
    t
    e
    H
    e
    a
    d
    e
    r
    (
    u
    n
    s
    i
    g
    n
    e
    d i
    n
    t p
    0
    , i
    n
    t p
    1
    )
    ;
    Accessing C from Python:
    R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    _
    W
    r
    i
    t
    e
    H
    e
    a
    d
    e
    r
    (
    w
    , h
    e
    a
    d
    e
    r
    )
    Python wrapper:
    R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    .
    s
    e
    t
    _
    s
    t
    a
    t
    u
    s
    (
    s
    e
    l
    f
    , c
    o
    d
    e
    )
    Andrey Petrov · @shazow

    View Slide

  63. Overcoming Challenges
    1. Don't share memory
    2. Translation layer
    3. Seriously, don't share memory
    Andrey Petrov · @shazow

    View Slide

  64. Challenge 3: Seriously, don't share memory
    Wait, what's a Go interface?
    Andrey Petrov · @shazow

    View Slide

  65. Challenge 3: Seriously, don't share memory
    Wait, what's a Go interface?
    To use it, we need to pass a pointer through
    ☞ Go ⇢ C ⇢ Python ⇢ C ⇢ Go

    Andrey Petrov · @shazow

    View Slide

  66. Challenge 3: Seriously, don't share memory
    Wait, what's a Go interface?
    To use it, we need to pass a pointer through
    ☞ Go ⇢ C ⇢ Python ⇢ C ⇢ Go

    Solution: Pointer Proxy!
    Andrey Petrov · @shazow

    View Slide

  67. Pointer Proxy
    PtrProxy
    ResponseWriter
    0xd34db33f
    PtrId
    1234
    Ref
    Deref
    Free
    Safe for Go Safe for C
    Andrey Petrov · @shazow

    View Slide

  68. Pointer Proxy
    t
    y
    p
    e p
    t
    r
    P
    r
    o
    x
    y s
    t
    r
    u
    c
    t {
    s
    y
    n
    c
    .
    M
    u
    t
    e
    x
    c
    o
    u
    n
    t u
    i
    n
    t
    l
    o
    o
    k
    u
    p m
    a
    p
    [
    u
    i
    n
    t
    ]
    u
    n
    s
    a
    f
    e
    .
    P
    o
    i
    n
    t
    e
    r
    }
    f
    u
    n
    c (
    p *
    p
    t
    r
    P
    r
    o
    x
    y
    ) R
    e
    f
    (
    p
    t
    r u
    n
    s
    a
    f
    e
    .
    P
    o
    i
    n
    t
    e
    r
    ) C
    .
    u
    i
    n
    t { .
    .
    . }
    f
    u
    n
    c (
    p *
    p
    t
    r
    P
    r
    o
    x
    y
    ) D
    e
    r
    e
    f
    (
    i
    d C
    .
    u
    i
    n
    t
    ) (
    u
    n
    s
    a
    f
    e
    .
    P
    o
    i
    n
    t
    e
    r
    , b
    o
    o
    l
    ) { .
    .
    . }
    f
    u
    n
    c (
    p *
    p
    t
    r
    P
    r
    o
    x
    y
    ) F
    r
    e
    e
    (
    i
    d C
    .
    u
    i
    n
    t
    ) { .
    .
    . }
    Now we can pass an opaque uint across enemy lines and it's perfectly safe.
    Andrey Petrov · @shazow

    View Slide

  69. Quick flashback: Translation layer
    One pointer proxy to rule them all.
    v
    a
    r c
    p
    o
    i
    n
    t
    e
    r
    s = P
    t
    r
    P
    r
    o
    x
    y
    (
    )
    Andrey Petrov · @shazow

    View Slide

  70. Quick flashback: Translation layer
    One pointer proxy to rule them all.
    v
    a
    r c
    p
    o
    i
    n
    t
    e
    r
    s = P
    t
    r
    P
    r
    o
    x
    y
    (
    )
    In the callback, reference to bind them. ⛓
    h
    t
    t
    p
    .
    H
    a
    n
    d
    l
    e
    F
    u
    n
    c
    (
    p
    a
    t
    t
    e
    r
    n
    , f
    u
    n
    c
    (
    w h
    t
    t
    p
    .
    R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    , r
    e
    q *
    h
    t
    t
    p
    .
    R
    e
    q
    u
    e
    s
    t
    ) {
    /
    / W
    r
    a
    p r
    e
    l
    e
    v
    a
    n
    t r
    e
    q
    u
    e
    s
    t f
    i
    e
    l
    d
    s i
    n a C
    -
    f
    r
    i
    e
    n
    d
    l
    y d
    a
    t
    a
    s
    t
    r
    u
    c
    t
    u
    r
    e
    .
    c
    r
    e
    q :
    = C
    .
    R
    e
    q
    u
    e
    s
    t
    { .
    .
    . }
    w
    P
    t
    r :
    = c
    p
    o
    i
    n
    t
    e
    r
    s
    .
    R
    e
    f
    (
    u
    n
    s
    a
    f
    e
    .
    P
    o
    i
    n
    t
    e
    r
    (
    &
    w
    )
    )
    .
    .
    .
    c
    p
    o
    i
    n
    t
    e
    r
    s
    .
    F
    r
    e
    e
    (
    w
    P
    t
    r
    )
    }
    )
    Andrey Petrov · @shazow

    View Slide

  71. Quick flashback: Translation layer
    One pointer proxy to rule them all.
    v
    a
    r c
    p
    o
    i
    n
    t
    e
    r
    s = P
    t
    r
    P
    r
    o
    x
    y
    (
    )
    In the callback, reference to bind them. ⛓
    h
    t
    t
    p
    .
    H
    a
    n
    d
    l
    e
    F
    u
    n
    c
    (
    p
    a
    t
    t
    e
    r
    n
    , f
    u
    n
    c
    (
    w h
    t
    t
    p
    .
    R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    , r
    e
    q *
    h
    t
    t
    p
    .
    R
    e
    q
    u
    e
    s
    t
    ) {
    /
    / W
    r
    a
    p r
    e
    l
    e
    v
    a
    n
    t r
    e
    q
    u
    e
    s
    t f
    i
    e
    l
    d
    s i
    n a C
    -
    f
    r
    i
    e
    n
    d
    l
    y d
    a
    t
    a
    s
    t
    r
    u
    c
    t
    u
    r
    e
    .
    c
    r
    e
    q :
    = C
    .
    R
    e
    q
    u
    e
    s
    t
    { .
    .
    . }
    w
    P
    t
    r :
    = c
    p
    o
    i
    n
    t
    e
    r
    s
    .
    R
    e
    f
    (
    u
    n
    s
    a
    f
    e
    .
    P
    o
    i
    n
    t
    e
    r
    (
    &
    w
    )
    )
    .
    .
    .
    c
    p
    o
    i
    n
    t
    e
    r
    s
    .
    F
    r
    e
    e
    (
    w
    P
    t
    r
    )
    }
    )
    With pointer proxy, dereference to find them.
    f
    u
    n
    c R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    _
    W
    r
    i
    t
    e
    H
    e
    a
    d
    e
    r
    (
    w
    P
    t
    r C
    .
    u
    i
    n
    t
    , h
    e
    a
    d
    e
    r C
    .
    i
    n
    t
    ) {
    w
    , _ :
    = c
    p
    o
    i
    n
    t
    e
    r
    s
    .
    D
    e
    r
    e
    f
    (
    w
    P
    t
    r
    )
    (
    *
    (
    *
    h
    t
    t
    p
    .
    R
    e
    s
    p
    o
    n
    s
    e
    W
    r
    i
    t
    e
    r
    )
    (
    w
    )
    )
    .
    W
    r
    i
    t
    e
    H
    e
    a
    d
    e
    r
    (
    i
    n
    t
    (
    h
    e
    a
    d
    e
    r
    )
    )
    }
    Andrey Petrov · @shazow

    View Slide

  72. Recap
    If our languages can speak with C, they can speak
    with each other.
    Andrey Petrov · @shazow

    View Slide

  73. Recap
    If our languages can speak with C, they can speak
    with each other.
    Be careful going in and out of runtimes.
    Andrey Petrov · @shazow

    View Slide

  74. Recap
    If our languages can speak with C, they can speak
    with each other.
    Be careful going in and out of runtimes.
    Be super-careful with sharing memory.
    Andrey Petrov · @shazow

    View Slide

  75. Recap
    If our languages can speak with C, they can speak
    with each other.
    Be careful going in and out of runtimes.
    Be super-careful with sharing memory.
    We'll need a translation layer to use non-trivial
    language constructs.
    Andrey Petrov · @shazow

    View Slide

  76. Other Considerations
    Andrey Petrov · @shazow

    View Slide

  77. Other Considerations
    Memory leaks
    Andrey Petrov · @shazow

    View Slide

  78. Other Considerations
    Memory leaks
    Race conditions
    Andrey Petrov · @shazow

    View Slide

  79. Other Considerations
    Memory leaks
    Race conditions
    Context switching overhead
    Andrey Petrov · @shazow

    View Slide

  80. Other Considerations
    Memory leaks
    Race conditions
    Context switching overhead
    Probably security issues because C is hard
    Andrey Petrov · @shazow

    View Slide

  81. Other Considerations
    Memory leaks
    Race conditions
    Context switching overhead
    Probably security issues because C is hard
    Architecture campanelle
    Andrey Petrov · @shazow

    View Slide

  82. A Palate Cleanser
    Andrey Petrov · @shazow

    View Slide

  83. A Palate Cleanser

    LOLBENCHMARKS!
    Andrey Petrov · @shazow

    View Slide

  84. LOLBENCHMARKS
    Andrey Petrov · @shazow

    View Slide

  85. LOLBENCHMARKS
    Name Total Req/Sec Time/Req
    go-net/http 1.115 8969.89 0.111
    gohttp-c 1.181 8470.97 0.118
    gohttp-python 1.285 7779.87 0.129
    gunicorn-flask 7.826 1277.73 0.783
    werkzeug-flask 15.029 665.37 1.503
    Conditions: a
    b
    doing 10,000 requests with 10 concurrency on my .
    Andrey Petrov · @shazow

    View Slide

  86. Thank you
    github.com/shazow/gohttplib
    hrku.co/gopythongo
    twitter.com/shazow
    shazow.net
    Andrey Petrov · @shazow

    View Slide