Slide 1

Slide 1 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Native Extensions: how do they work ? Lourens Naudé RailsWayCon 2012 Berlin - http://railswaycon.com/2012 Wednesday, June 6, 12

Slide 2

Slide 2 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Operations @ WildfireApp.com Bio Wednesday, June 6, 12

Slide 3

Slide 3 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Agenda Important, yet volatile When things go wrong FFI VS C api GC Threading Wednesday, June 6, 12

Slide 4

Slide 4 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 ERROR: Failed to build gem native extension. Seen this ? Wednesday, June 6, 12

Slide 5

Slide 5 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 [BUG] Segmentation fault this ? Wednesday, June 6, 12

Slide 6

Slide 6 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 dyld: Symbol not found: _mysql2_set_field_string_encoding Referenced from: ... Expected in: flat namespace or this ? Wednesday, June 6, 12

Slide 7

Slide 7 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Your critical path and I/O depends on it. Why this is important ? Wednesday, June 6, 12

Slide 8

Slide 8 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Often misunderstood ... Wednesday, June 6, 12

Slide 9

Slide 9 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Bindings ... not only for performance Wednesday, June 6, 12

Slide 10

Slide 10 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Integration requirements Lower subsystems Commercial static linking C lib code reuse Instrumentation Wednesday, June 6, 12

Slide 11

Slide 11 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Much more likely to break than ANY Ruby code. Volatile components Wednesday, June 6, 12

Slide 12

Slide 12 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Breakage - operating system First run on OS OS agnostic library Extension, NOT Upgrades Wednesday, June 6, 12

Slide 13

Slide 13 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Breakage - interpreter Interpreter version bump Deprecations GC changes Threading changes Wednesday, June 6, 12

Slide 14

Slide 14 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Breakage - implementation MRI only ? Encodings Non-standard macros Wednesday, June 6, 12

Slide 15

Slide 15 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Breakage - library ABI Incompatible system lib apt-get, homebrew etc. Extension should assert versions Wednesday, June 6, 12

Slide 16

Slide 16 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Breakage - operations lib removal (dynamic linking) Dependencies bumped Incompatible compiler versions New AMI Wednesday, June 6, 12

Slide 17

Slide 17 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Breakage - author sloppiness No GC integration No threading support Memory allocs will fail Ignore error returns Wednesday, June 6, 12

Slide 18

Slide 18 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Breakage - malpractice Read the manual ? Can it be called out to ? Ruby and C disconnect Respect resources Wednesday, June 6, 12

Slide 19

Slide 19 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 System or tarball dependency ? Distribution Wednesday, June 6, 12

Slide 20

Slide 20 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Distribution - system Dev + ops overhead Package manager mkmf is stable Hard to enforce versions Bug reports: error surface Wednesday, June 6, 12

Slide 21

Slide 21 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Distribution - tarball No dev (or ops) overhead !! OS agnostic installs !! Sandbox - beta versions Wednesday, June 6, 12

Slide 22

Slide 22 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 require “mysql2” Loading Wednesday, June 6, 12

Slide 23

Slide 23 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 What happens dlopen() or similar mysql2.dylib Init_mysql2 symbol Modules, objects and global state Method prototypes Wednesday, June 6, 12

Slide 24

Slide 24 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 VALUE mMysql2, cMysql2Error; /* Ruby Extension initializer */ void Init_mysql2() { mMysql2 = rb_define_module("Mysql2"); cMysql2Error = rb_const_get(mMysql2, rb_intern("Error")); init_mysql2_client(); init_mysql2_result(); } eg. mysql2 Wednesday, June 6, 12

Slide 25

Slide 25 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Reporting problems When things go wrong Wednesday, June 6, 12

Slide 26

Slide 26 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 OS and compiler OS version Compiler version Platform: 32 or 64 bit Wednesday, June 6, 12

Slide 27

Slide 27 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 library library and version Package manager compile ? Installed for correct platform ? Wednesday, June 6, 12

Slide 28

Slide 28 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 methodmissing:lib lourens$ otool -L rbczmq_ext.bundle rbczmq_ext.bundle: /Users/lourens/.rvm/rubies/ruby-1.8.7-p357/lib/libruby.dylib (compatibility version 1.8.0, current version 1.8.7) /Users/lourens/projects/rbczmq/ext/rbczmq/dst/lib/libzmq. 1.dylib (compatibility version 2.0.0, current version 2.1.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0) /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0) /usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 52.0.0) Linked versions Wednesday, June 6, 12

Slide 29

Slide 29 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Ruby install Implementation and version How was it compiled ? Native C API ? FFI gem ? Wednesday, June 6, 12

Slide 30

Slide 30 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 1.8.7 :001 > require 'rbconfig' 1.8.7 :002 > pp RbConfig::CONFIG {"build"=>"i686-apple-darwin11.0.1", "LDSHARED"=>"cc -arch x86_64 -dynamiclib -undefined suppress -flat_namespace", "configure_args"=> " '--prefix=/Users/lourens/.rvm/rubies/ruby-1.8.7-p352' '--enable- shared' '--disable-install-doc' 'CC=/usr/bin/gcc-4.2' 'CFLAGS=-arch x86_64 -g -Os -pipe -no-cpp-precomp' 'LDFLAGS=-arch x86_64 - bind_at_load'", "CPP"=>"/usr/bin/gcc-4.2 -E" Ruby config Wednesday, June 6, 12

Slide 31

Slide 31 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Questions to ask Program under stress ? Non-deterministic ? (GC && threads) Conflicting native gem requires ? Wednesday, June 6, 12

Slide 32

Slide 32 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Runtime context Context Wednesday, June 6, 12

Slide 33

Slide 33 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Runtime - gdb Available on most systems Tracing execution C backtrace gdb -c gdb -p Wednesday, June 6, 12

Slide 34

Slide 34 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 (gdb) bt 3 #0 0x00007fff8f51dda8 in memmove$VARIANT$sse42 () #1 0x0000000104b63345 in rb_thread_save_context (th=0x104dd50e0) at eval.c:10627 #2 0x0000000104b6e071 in rb_thread_schedule () at eval.c:11307 (More stack frames follow...) Example backtrace Wednesday, June 6, 12

Slide 35

Slide 35 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Runtime - strace System calls && signals Observing app <=> OS System backtrace strace strace -p Wednesday, June 6, 12

Slide 36

Slide 36 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 ( Apple fanboys ) sudo dtruss sudo dtruss -p Wednesday, June 6, 12

Slide 37

Slide 37 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 select(14, [5 7 13], [], [], {0, 90519}) = 0 (Timeout) gettimeofday({1328183002, 561382}, NULL) = 0 munmap(0x7f576eaee000, 41766912) = 0 brk(0x16f685000) = 0x16f685000 brk(0x16a6db000) = 0x16a6db000 ^CProcess 5360 detached Example system trace Wednesday, June 6, 12

Slide 38

Slide 38 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Runtime - lsof Files, pipes, sockets && devices File ownership Assert correct libs are loaded Enumerate file descriptors lsof -p Wednesday, June 6, 12

Slide 39

Slide 39 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 ruby 22103 user 0r CHR 1,3 0t0 735 /dev/null ruby 22103 user 1u CHR 1,3 0t0 735 /dev/null ruby 22103 user 2u CHR 1,3 0t0 735 /dev/null ruby 22103 user 3r FIFO 0,8 0t0 324848777 pipe ruby 22103 user 4w FIFO 0,8 0t0 324848740 pipe ruby 22103 user 5u IPv4 284775119 0t0 TCP *:17673 (LISTEN) Process descriptors Wednesday, June 6, 12

Slide 40

Slide 40 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Managing Risk Checklist Wednesday, June 6, 12

Slide 41

Slide 41 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Devil’s advocate Do you really need an extension ? CLI library interface ? Wrapped library best practices ? Resource limits ? Ruby implementation limits ? Wednesday, June 6, 12

Slide 42

Slide 42 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Best practices Do some research Shell out for once off requests Know tools for when things go wrong Detail bug reports Native dependencies in gems gem pristine -all Wednesday, June 6, 12

Slide 43

Slide 43 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Foreign Function Interface FFI Wednesday, June 6, 12

Slide 44

Slide 44 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Code written in one language can call code in another. libffi Wednesday, June 6, 12

Slide 45

Slide 45 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 gem install ffi Ruby integration Wednesday, June 6, 12

Slide 46

Slide 46 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Disclaimer Never written a FFI extension Know the C API very well Many folks in the same boat Wednesday, June 6, 12

Slide 47

Slide 47 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Evolving Ruby ecosystem Why it matters Wednesday, June 6, 12

Slide 48

Slide 48 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 JRuby C API since 1.6 Not perfect, but compiles most exts Deprecated Great FFI support Wednesday, June 6, 12

Slide 49

Slide 49 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Rubinius Very stable C API Compiles most MRI extensions Great FFI support Wednesday, June 6, 12

Slide 50

Slide 50 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 MRI Standard C API Good FFI support, flaky on 1.8 Wednesday, June 6, 12

Slide 51

Slide 51 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Caveats Performance penalty Negligible out of critical path Dependencies - libffi + ffi gem More moving parts Wednesday, June 6, 12

Slide 52

Slide 52 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Garbage Collector Integration Wednesday, June 6, 12

Slide 53

Slide 53 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 struct RData { struct RBasic basic; void (*dmark) _((void*)); void (*dfree) _((void*)); void *data; }; GC callbacks Wednesday, June 6, 12

Slide 54

Slide 54 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 GC mark callback Invoked during mark phase Let GC know of other objects Wednesday, June 6, 12

Slide 55

Slide 55 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 GC free callback Invoked when no refs found Frees self and other resources Sockets, engines etc. Wednesday, June 6, 12

Slide 56

Slide 56 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 typedef struct { size_t delay; size_t times; Bool cancelled; VALUE callback; } zmq_timer_wrapper; GC - struct example Wednesday, June 6, 12

Slide 57

Slide 57 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 VALUE timer; zmq_timer_wrapper *tr = NULL; timer = Data_Make_Struct(rb_cZmqTimer, zmq_timer_wrapper, rb_czmq_mark_timer, rb_czmq_free_timer_gc, tr); GC - struct integration Wednesday, June 6, 12

Slide 58

Slide 58 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 static void rb_czmq_mark_timer(void *ptr) { zmq_timer_wrapper *timer = (zmq_timer_wrapper *)ptr; rb_gc_mark(timer->callback); } GC - mark callback example Wednesday, June 6, 12

Slide 59

Slide 59 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 static void rb_czmq_free_timer_gc(void *ptr) { zmq_timer_wrapper *timer = (zmq_timer_wrapper *)ptr; if (timer) xfree(timer); } GC - free callback example Wednesday, June 6, 12

Slide 60

Slide 60 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Threads Integration Wednesday, June 6, 12

Slide 61

Slide 61 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 int rb_thread_select _((int, fd_set *, fd_set *, fd_set *, struct timeval *)); rb_thread_select Wednesday, June 6, 12

Slide 62

Slide 62 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 rb_thread_select User space replacement for select() Allows other threads to run I/O bound threads Blocks process otherwise mysql VS mysql2 Wednesday, June 6, 12

Slide 63

Slide 63 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 GIL API for releasing the GIL MRI 1.9 and Rubinuis Calling C funcs + system calls Unstable API Wednesday, June 6, 12

Slide 64

Slide 64 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 static VALUE rb_czmq_nogvl_zctx_destroy(void *ptr) { zmq_ctx_wrapper *ctx = ptr; zctx_destroy(&ctx->ctx); return Qnil; } rb_thread_blocking_region(rb_czmq_nogvl_zctx_ destroy, ctx, RUBY_UBF_IO, 0); rb_thread_select() Wednesday, June 6, 12

Slide 65

Slide 65 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Passing thoughts Vibrant ruby ecosystem Extensions: brittle integration point Tokaido ( formerly Rails.app ) Shipping binary builds http://yehudakatz.com/2012/06/05/ tokaido-status-update- implementation-details Wednesday, June 6, 12

Slide 66

Slide 66 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 Questions ? O fim Wednesday, June 6, 12

Slide 67

Slide 67 text

Wildfire Interactive, Inc. | 1600 Seaport Boulevard, Suite 500, Redwood City, CA 94063 | (888) 274-0929 @methodmissing github.com/methodmissing Thanks! Wednesday, June 6, 12