Upgrade to Pro — share decks privately, control downloads, hide ads and more …

node-ffi

othree
October 12, 2014

 node-ffi

othree

October 12, 2014
Tweet

More Decks by othree

Other Decks in Technology

Transcript

  1. node-ffi
    othree jsdc

    View Slide

  2. @othree
    othree.net MozTW
    F2E at HTC PhD Candidate

    View Slide

  3. Topics
    r3 ffi
    node-ffi
    node-ffi
    packages
    node-r3

    View Slide

  4. r3
    ˖ 4VQFSGBTUSPVUFSMJCXSJUUFOJO$
    ˖ CZDT
    https://github.com/c9s/r3

    View Slide

  5. r3
    ˖ #BTFEPO%'" 焷㹁剤ꣳ朜䢀荈⹛堥

    ˖ 1SFDPNQJMFSPVUFTJOUPQSFYUSFF
    ˖ UJNFTGBTUFSUIBO+PVSOFZ
    http://c9s.blogspot.tw/2014/05/r3-url-router-library.html

    View Slide

  6. How to Use libr3
    ˖ $SFBUFUSFF
    ˖ *OTFSUSPVUFXJUIEBUB
    ˖ $PNQJMFUSFF
    ˖ .BUDISPVUFBOEHFUUIFEBUB

    View Slide

  7. Sample 1/2
    n = r3_tree_create(10);!
    !
    int route_data = 3;!
    !
    r3_tree_insert_routel(n, METHOD_GET, "/blog/post", !
    sizeof("/blog/post") - 1, &route_data );!
    !
    int err = r3_tree_compile(n, &errstr);

    View Slide

  8. Sample 1/2
    n = r3_tree_create(10);!
    !
    int route_data = 3;!
    !
    r3_tree_insert_routel(n, METHOD_GET, "/blog/post", !
    sizeof("/blog/post") - 1, &route_data );!
    !
    int err = r3_tree_compile(n, &errstr);
    Create Tree

    View Slide

  9. Sample 1/2
    n = r3_tree_create(10);!
    !
    int route_data = 3;!
    !
    r3_tree_insert_routel(n, METHOD_GET, "/blog/post", !
    sizeof("/blog/post") - 1, &route_data );!
    !
    int err = r3_tree_compile(n, &errstr);
    Insert Route

    View Slide

  10. Sample 1/2
    n = r3_tree_create(10);!
    !
    int route_data = 3;!
    !
    r3_tree_insert_routel(n, METHOD_GET, "/blog/post", !
    sizeof("/blog/post") - 1, &route_data );!
    !
    int err = r3_tree_compile(n, &errstr);
    Data

    View Slide

  11. Sample 1/2
    n = r3_tree_create(10);!
    !
    int route_data = 3;!
    !
    r3_tree_insert_routel(n, METHOD_GET, "/blog/post", !
    sizeof("/blog/post") - 1, &route_data );!
    !
    int err = r3_tree_compile(n, &errstr);
    Compile

    View Slide

  12. View Slide

  13. Sample 2/2
    match_entry * entry = match_entry_create("/blog/post");!
    entry->request_method = METHOD_GET;!
    !
    route *matched_route = r3_tree_match_route(n, entry);!
    matched_route->data; // The Data!
    !
    match_entry_free(entry);!
    r3_tree_free(n);

    View Slide

  14. Sample 2/2
    match_entry * entry = match_entry_create("/blog/post");!
    entry->request_method = METHOD_GET;!
    !
    route *matched_route = r3_tree_match_route(n, entry);!
    matched_route->data; // The Data!
    !
    match_entry_free(entry);!
    r3_tree_free(n);
    Create Entry

    View Slide

  15. Sample 2/2
    match_entry * entry = match_entry_create("/blog/post");!
    entry->request_method = METHOD_GET;!
    !
    route *matched_route = r3_tree_match_route(n, entry);!
    matched_route->data; // The Data!
    !
    match_entry_free(entry);!
    r3_tree_free(n);
    Match Route

    View Slide

  16. Sample 2/2
    match_entry * entry = match_entry_create("/blog/post");!
    entry->request_method = METHOD_GET;!
    !
    route *matched_route = r3_tree_match_route(n, entry);!
    matched_route->data; // The Data!
    !
    match_entry_free(entry);!
    r3_tree_free(n);
    Route Data

    View Slide

  17. match_entry
    ˖ 6TFEGPSDBQUVSFWBSJBCMFT
    ˖ "EENFUIPEDPOEJUJPO
    ˖ 'VUVSF
    ˖ *1NBTL
    ˖ 1PSUSBOHF

    View Slide

  18. Captures
    ˖ 6TF{variable_name}!
    ˖ $BOVTFSFHVMBSFYQSFTTJPO

    View Slide

  19. View Slide

  20. Sample 2/2
    match_entry * entry = match_entry_create(“/blog/post/1/2/3“);!
    entry->request_method = METHOD_GET; // Method Condition!
    !
    route *matched_route = r3_tree_match_route(n, entry);!
    !
    matched_route->data; // The Data!
    entry->vars; //Captured Vars, a string array!
    !
    r3_tree_free(n);

    View Slide

  21. May I Use r3 in node

    View Slide

  22. Yes.

    View Slide

  23. How?

    View Slide

  24. How
    ˖ /PEFKTFYUFOTJPO
    ˖ 8SJUF$$ DBBTJOPEFS
    ˖ 'PSFJHO'VODUJPO*OUFSGBDF ''*

    ˖ 6TFEZOBNJDMJC

    View Slide

  25. Why
    ˖ *UNJHIUGBTUFSUIBODVSSFOUTPMVUJPO
    ˖ 㔔捀䧮〳⟃#FDBVTF*DBO
    ˖ *BNXSJUJOHNZ1I%UIFTJT *BNXJMMJOHUPEP
    BOZUIJOHFYDFQUXSJUJOHUIFTJT

    View Slide

  26. Foreign Function
    Interface

    View Slide

  27. l
    "GPSFJHOGVODUJPOJOUFSGBDF ''*
    JT
    BNFDIBOJTNCZXIJDIBQSPHSBN
    XSJUUFOJOPOFQSPHSBNNJOH
    MBOHVBHFDBODBMMSPVUJOFTPSNBLF
    VTFPGTFSWJDFTXSJUUFOJOBOPUIFS
    https://en.wikipedia.org/wiki/Foreign_function_interface

    View Slide

  28. ˖ #ZVOEFSTUBOEDBMMJOHDPOWFOUJPO
    ˖ ,OPXIPXUPDBMMGPSFJHOGVODUJPOT TFOE
    BSHVNFOU BOESFBESFUVSOWBMVF
    ˖ *OBTTFNCMZMBOHVBHFMFWFM
    ˖ $BMM$EZOBNJDMJCJONPTUDBTFT

    View Slide

  29. __cdecl
    val = sumExample(2,3)
    ; // push arguments to the stack, from right to left!
    push 3 !
    push 2 !
    !
    ; // call the function!
    call _sumExample !
    !
    ; // cleanup the stack by adding the size of the arguments to!
    ; // ESP register!
    add esp,8 !
    !
    ; // copy the return value from EAX to a local variable (int c)!
    mov dword ptr [c],eax

    View Slide

  30. node-ffi

    View Slide

  31. l
    OPEFJTB/PEFKTBEEPOGPSMPBEJOH
    BOEDBMMJOHEZOBNJDMJCSBSJFTVTJOH
    QVSF+BWB4DSJQU*UDBOCFVTFEUP
    DSFBUFCJOEJOHTUPOBUJWFMJCSBSJFT
    XJUIPVUXSJUJOHBOZ$DPEF
    https://github.com/node-ffi/node-ffi

    View Slide

  32. So node-ffi Knows
    ˖ )PXUPDBMMGVODUJPOJO$$EZOBNJDMJC
    ˖ )PXUPDPOWFSU+BWB4DSJQUEBUBUP$$EBUB
    ˖ )PXUPTFOEQBSBNFUFS
    ˖ )PXUPHSBCSFUVSOWBMVF

    View Slide

  33. ˖ #Z!5PP5BMM/BUF

    View Slide

  34. @TooTallNate
    ˖ /BUIBO3BKMJDI
    ˖ /PEFKTDPSFDPNNJUUFS
    ˖ 0OFBVUIPSPG/PEFKTJO"DUJPO
    ˖ -PUTPGSFMBUFEQBDLBHF
    ˖ /PE0CK$ /PEFKT̠0CKFDUJWF$CSJEHF

    View Slide

  35. ffi Packages
    ffi ref
    ref-struct ref-array

    View Slide

  36. ffi Foreign Function Call
    ref Reference Tools
    ref-struct Struct Helper
    ref-array Array Helper

    View Slide

  37. Example
    var ffi = require('ffi');!
    !
    var libm = ffi.Library('libm', {!
    'ceil': [ 'double', [ 'double' ] ]!
    });!
    !
    libm.ceil(1.5); // 2

    View Slide

  38. Example
    var ffi = require('ffi');!
    !
    var libm = ffi.Library('libm', {!
    'ceil': [ 'double', [ 'double' ] ]!
    });!
    !
    libm.ceil(1.5); // 2
    Library name!
    Use dlopen

    View Slide

  39. Example
    var ffi = require('ffi');!
    !
    var libm = ffi.Library('libm', {!
    'ceil': [ 'double', [ 'double' ] ]!
    });!
    !
    libm.ceil(1.5); // 2
    A function named ‘ceil’ return double

    Take one double parameter

    View Slide

  40. Example
    var ffi = require('ffi');!
    !
    var libm = ffi.Library('libm', {!
    'ceil': [ 'double', [ 'double' ] ]!
    });!
    !
    libm.ceil(1.5); // 2
    return type

    View Slide

  41. Example
    var ffi = require('ffi');!
    !
    var libm = ffi.Library('libm', {!
    'ceil': [ 'double', [ 'double' ] ]!
    });!
    !
    libm.ceil(1.5); // 2
    arguments type

    View Slide

  42. Types
    void bool byte pointer
    (u)short (u)int (u)int16 (u)int32
    (u)int64 (u)longlong size_t float
    (u)char string object

    View Slide

  43. Example
    var ffi = require('ffi');!
    !
    var libm = ffi.Library('libm', {!
    'ceil': [ 'double', [ 'double' ] ]!
    });!
    !
    libm.ceil(1.5); // 2
    Call ceil

    View Slide

  44. To Use node-ffi
    ˖ 3FBEIFBEFSMF I

    ˖ 8SJUFffi.LibraryEFOJUJPO
    ˖ 6TFJU

    View Slide

  45. math.h
    http://www.cplusplus.com/reference/cmath/ceil/
    double ceil (double x);
    var libm = ffi.Library('libm', {!
    'ceil': [ 'double', [ 'double' ] ]!
    });

    View Slide

  46. math.h
    http://www.cplusplus.com/reference/cmath/ceil/
    double ceil (double x);
    var libm = ffi.Library('libm', {!
    'ceil': [ 'double', [ 'double' ] ]!
    });

    View Slide

  47. math.h
    http://www.cplusplus.com/reference/cmath/ceil/
    double ceil (double x);
    var libm = ffi.Library('libm', {!
    'ceil': [ 'double', [ 'double' ] ]!
    });

    View Slide

  48. math.h
    http://www.cplusplus.com/reference/cmath/ceil/
    double ceil (double x);
    var libm = ffi.Library('libm', {!
    'ceil': [ 'double', [ 'double' ] ]!
    });

    View Slide

  49. r3.h

    View Slide

  50. View Slide

  51. View Slide

  52. Struct?

    View Slide

  53. Struct
    ˖ "TUSVDUJTBDUVBMMZBQPJOUFS
    ˖ 0LUPVTFQPJOUFS
    ˖ /PUPLUPVTFQPJOUFSJGXBOUUPMPBEJUTQSPQFSUZ
    ˖ 6TFSFGTUSVDU

    View Slide

  54. struct _edge {!
    char * pattern; // 8 bytes!
    node * child; // 8 bytes!
    unsigned char pattern_len; // 1 byte!
    unsigned char opcode:4; // 4 bit!
    unsigned char has_slug:1; // 1 bit!
    };
    var StructType = require('ref-struct');!
    !
    var edge = StructType({!
    pattern: "string",!
    child: "pointer",!
    pattern_len: "ushort",!
    opcode: "uchar",!
    has_slug: "uchar"!
    });

    View Slide

  55. ref-struct
    ˖ $SFBUF"#*DPNQMJBOUTUSVDUJOTUBODFTPOUPQPG
    #VFST
    ˖ "#* "QQMJDBUJPO#JOBSZ*OUFSGBDF

    ˖ UIFTJ[FT MBZPVU BOEBMJHONFOUPGEBUBUZQFT
    ˖
    https://en.wikipedia.org/wiki/Application_binary_interface

    View Slide

  56. https://mentorembedded.github.io/cxx-abi/abi.html

    View Slide

  57. https://mentorembedded.github.io/cxx-abi/

    View Slide

  58. Struct in Struct?

    View Slide

  59. typedef struct {!
    str_array * vars;!
    const char * path; // current path to dispatch!
    int path_len; // the length of the current path!
    int request_method; // current request method!
    void * data; // route ptr!
    char * host; // the request host!
    !
    ...

    View Slide

  60. typedef struct {!
    str_array * vars;!
    const char * path; // current path to dispatch!
    int path_len; // the length of the current path!
    int request_method; // current request method!
    void * data; // route ptr!
    char * host; // the request host!
    !
    ...
    var ref = require('ref');!
    !
    var str_array = StructType({ ... });!
    !
    var match_entry = StructType({!
    vars: ref.refType(str_array),!
    path: "string",!
    path_len: "int",!
    request_method: "int",!
    data: "pointer",!
    host: "pointer",!
    ...

    View Slide

  61. lSFGJTBOBUJWFBEEPOGPS/PEFKT
    UIBUBJETJOEPJOH$QSPHSBNNJOH
    JO+BWB4DSJQU CZFYUFOEJOHUIF
    CVJMUJO#VFSDMBTT
    https://tootallnate.github.io/ref/

    View Slide

  62. View Slide

  63. ref.refType
    ˖ (FUSFGFSFODFUPEBUBUZQF

    View Slide

  64. l3FUVSOTBOFXDMPOFPGUIFHJWFO
    UZQFPCKFDU XJUIJUTJOEJSFDUJPO
    MFWFMJODSFNFOUFECZ
    https://tootallnate.github.io/ref/

    View Slide

  65. ref.refType
    ˖ (FUSFGFSFODFUPEBUBUZQF
    ˖ indirectionNFBOTUIFDPVOUPG*

    View Slide

  66. ref.refType
    StructType({!
    var1: str_array,!
    var2: ref.refType(str_array)!
    });
    str_array var1;!
    str_array * var2;

    View Slide

  67. ref.refType
    StructType({!
    var1: str_array,!
    var2: ref.refType(str_array)!
    });
    str_array var1;!
    str_array * var2;

    View Slide

  68. ref.refType
    StructType({!
    var1: str_array,!
    var2: ref.refType(str_array)!
    });
    str_array var1;!
    str_array * var2;

    View Slide

  69. ref.refType
    StructType({!
    var1: str_array,!
    var2: ref.refType(str_array),!
    var3: ref.refType(ref.refType(str_array)),!
    });
    str_array var1;!
    str_array * var2;!
    str_array **var3;

    View Slide

  70. Back to r3.h

    View Slide

  71. View Slide

  72. View Slide

  73. #define
    ˖ $QSFQSPDFTTPS
    ˖ 3FQMBDFUIFTUSJOHJOTPVSDFDPEFT
    ˖ 1SPDFTTCFGPSFDPNQJMF
    ˖ /PUSFBMGVODUJPO

    View Slide

  74. #define r3_tree_insert_path(n,p,d) r3_tree_insert_pathl_ex(n,p,s
    var libr3 = ffi.Library('libr3', {!
    "r3_tree_insert_pathl_ex": ["pointer", ["pointer", "string", "
    });!
    !
    !
    var r3_tree_insert_path = function (tree, path, data) {!
    return libr3.r3_tree_insert_pathl_ex(tree, path, path.length,
    };

    View Slide

  75. r3.h

    View Slide

  76. r3.h
    ˖ MJOFT
    ˖ TUSVDUT
    ˖ NFUIPET
    -PUTPGXPSL

    View Slide

  77. node-ffi-generate
    ˖ "VUPNBUJDHFOFSBUFEFOJUJPOGSPNIMF
    ˖ $POT
    ˖ 3FTVMUJTUPPEFUBJM UPPCJH
    ˖ .JHIUOPUTVJUGPSVTF
    ˖ EFOF
    https://github.com/tjfontaine/node-ffi-generate

    View Slide

  78. node-r3
    ˖ 0OMZEFOFOFDFTTBSZNFUIPET
    ˖ NFUIPET
    ˖ 5SFFDSFBUF DPNQJMF EVNQ NBUDI GSFF
    ˖ *OTFSUSPVUF QBUI
    ˖ .BUDI@FOUSZDSFBUF GSFF

    View Slide

  79. Now We Can Write
    ffi.Library Define for r3

    View Slide

  80. 羳

    View Slide

  81. ㆭ剚鸏랃갫ⵄ

    View Slide

  82. ㉏겗
    Route Data

    View Slide

  83. route * r3_tree_insert_routel(node *tree, int method,

    const char *path, int path_len, void *data);

    View Slide

  84. route * r3_tree_insert_routel(node *tree, int method,

    const char *path, int path_len, void *data);

    View Slide

  85. Route Data
    ˖ 3PVUFEBUBJTWPJEQPJOUFS
    ˖ $BOQPJOUUPBOZUZQFPGEBUB
    ˖ MJCSPOMZTUPSFUIFQPJOUFS

    View Slide

  86. Pointer?

    View Slide

  87. Pointer in JS
    ˖ 5IFSFJTOPSFBMQPJOUFSJO+BWB4DSJQU
    ˖ #VUZPVDBOVTF#VFS

    View Slide

  88. Buffer
    ˖ /PEFKTPOMZ
    ˖ #VFSJTBDIVOLPGNFNPSZJOTQFDJFEBEESFTT
    ˖ $BOCFUZQFMFTT TJ[FDBOCF
    ˖ OPEFEFBMQPJOUFSBTCVFS

    View Slide

  89. Example 1/2
    var tree = libr3.r3_tree_create(10);!
    !
    var data = new Buffer(data_str + '\u0000');!
    !
    r3_tree_insert_route(tree, 'GET','/path', data);

    View Slide

  90. Example 2/2
    var node = libr3.r3_tree_match_route(tree, entry);!
    !
    var data = ref.deref(node).data;
    https://github.com/othree/node-r3/blob/46e29f72bbf68097ed66fd151f9ef42d5a3ede05/node-r3.js

    View Slide

  91. ref.deref
    ˖ %FSFGFSFODF
    ˖ (FUWBMVFGSPNCVFS
    ˖ *OUIJTDBTF EFSFGXJMMHFUBTUSVDU

    "OEJUTEBUBBUUSJCVUFJTXIBUXFXBOU

    View Slide

  92. The Data
    ˖ 5IFEBUBXFHPUJTBOPUIFSCVFSJOTUBODF
    ˖ 8FTFOEQPJOUFSPGUIJTCVFSUPSXIFOJOTFSU
    SPVUF
    ˖ 8FOFFEUPEFSFGFSFODFJUUPHFUSFBMEBUBWBMVF

    View Slide

  93. BUT

    View Slide

  94. The Problem
    ˖ %FSFGFSFODFdataXJMMHFUOPUIJOH
    ˖ #FDBVTFUIFTJ[FPGdataJTBOEUIFUZQFJT
    VOLOPXO

    View Slide

  95. Solution 1
    ˖ 4FUEBUBUZQFBOETJ[F
    • buffer.type!
    • ref.reinterpret

    View Slide

  96. ref.reinterpret
    ˖ 3FTJ[FCVFS
    ˖ :PVOFFEUPLOPXUIFTJ[FPGZPVSEBUB

    View Slide

  97. Cons
    ˖ )BSEUPJNQMFNFOUWBSJPVTEBUBUZQF
    ˖ *GZPVEPJU NJHIUIVSUQFSGPSNBODF
    ˖ )BSEUPEFTJHO"1*

    View Slide

  98. Solution 2
    ˖ "MXBZTVTFTUSJOH
    ˖ ref.readCString

    View Slide

  99. ref.readCString
    ˖ 3FBETUSJOHGSPNCVFS VOUJM00
    ˖ /PUTUPQXIFONFFUCVFSFOE

    View Slide

  100. var data = new Buffer(data_str + '\u0000');

    View Slide

  101. var data = ref.readCString(ref.deref(node).data, 0);

    View Slide

  102. Cons
    ˖ 3PVUFEBUBJTMJNJUFEUPTUSJOHUZQF

    View Slide

  103. ˖ "GUFSTPMWFSTUJTTVF
    ˖ 8FIBWFSTUVTBCMFOPEFS
    ˖ #VUUIFQFSGPSNBODFJTWFSZCBE
    ˖ 4MPXFSUIBOEJSFDUPS

    View Slide

  104. ㉏겗
    Performance

    View Slide

  105. Spec
    ˖ 6TFUIFTBNFUSFFJOSUFTUTCFODI
    ˖ 3VOPOJ.BD
    ˖ ()[*OUFM$PSFJ
    ˖ (#.)[%%3
    https://github.com/c9s/r3/blob/master/tests/bench.c

    View Slide

  106. Route req/s
    director ~2200
    node-r3 0.0.1 ~1900
    'PSVOLOPXOSFBTPO

    *DBOOPUSFQSPEVDFUIJTOVNCFS

    View Slide

  107. What Takes Time
    ˖ %BUBUSBOTGPSN
    ˖ $BMMGPSFJHOGVODUJPO

    View Slide

  108. Transform String
    ˖ /FXCVFSGSPNHJWFOEBUBTUSJOH
    ˖ 3FBE$TUSJOHGSPNQPJOUFS

    View Slide

  109. data = new Buffer(data + '\u0000');!
    r3_tree_insert_path(this.tree, route, data);
    var node = r3_tree_match(this.tree, path, entry);!
    !
    var data = ref.readCString(node.deref().data, 0);

    View Slide

  110. How to Skip Transform
    ˖ 4UPSFEBUBJO+BWB4DSJQUTJEF
    ˖ 6TFJOUFHFSJOEFYBTEBUB

    View Slide

  111. var i = this.i++;!
    this.data[i] = data;!
    !
    var iref = ref.alloc('int', i);!
    !
    libr3.r3_tree_insert_route(this.tree, method, route, iref);
    var node = libr3.r3_tree_match_route(this.tree, entry);!
    !
    var index = node.deref().data.reinterpret(4).readUInt32LE(0);!
    !
    var data = this.data[index];

    View Slide

  112. var i = this.i++;!
    this.data[i] = data;!
    !
    var iref = ref.alloc('int', i);!
    !
    libr3.r3_tree_insert_route(this.tree, method, route, iref);
    var node = libr3.r3_tree_match_route(this.tree, entry);!
    !
    var index = node.deref().data.reinterpret(4).readUInt32LE(0);!
    !
    var data = this.data[index];
    Store Data

    View Slide

  113. ref.alloc
    ˖ $SFBUFCVFSCZHJWFUZQFTJ[FBOEWBMVF

    View Slide

  114. var i = this.i++;!
    this.data[i] = data;!
    !
    var iref = ref.alloc('int', i);!
    !
    libr3.r3_tree_insert_route(this.tree, method, route, iref);
    var node = libr3.r3_tree_match_route(this.tree, entry);!
    !
    var index = node.deref().data.reinterpret(4).readUInt32LE(0);!
    !
    var data = this.data[index];
    Data for r3

    View Slide

  115. var i = this.i++;!
    this.data[i] = data;!
    !
    var iref = ref.alloc('int', i);!
    !
    libr3.r3_tree_insert_route(this.tree, method, route, iref);
    var node = libr3.r3_tree_match_route(this.tree, entry);!
    !
    var index = node.deref().data.reinterpret(4).readUInt32LE(0);!
    !
    var data = this.data[index];
    Resize Buffer

    View Slide

  116. var i = this.i++;!
    this.data[i] = data;!
    !
    var iref = ref.alloc('int', i);!
    !
    libr3.r3_tree_insert_route(this.tree, method, route, iref);
    var node = libr3.r3_tree_match_route(this.tree, entry);!
    !
    var index = node.deref().data.reinterpret(4).readUInt32LE(0);!
    !
    var data = this.data[index];
    Read Index

    View Slide

  117. readUInt32LE
    ˖ /PEFOBUJWFNFUIPE
    ˖ 3FBEVOTJHOFEJOUWBMVFGSPNCVFS

    View Slide

  118. Route req/s
    director ~2200
    node-r3 0.0.1 ~1900
    node-r3 0.0.3 ~5000

    View Slide

  119. More Pros
    ˖ /PNPSFMJNJUBUJPOPOEBUBUZQF
    ˖ "MM+4OBUJWFEBUBUZQFDBOCFVTF

    View Slide

  120. How About Foreign Calls
    ˖ 8IBUXFVTFE
    ˖ S@USFF@DSFBUF S@USFF@GSFF
    ˖ S@USFF@JOTFSU@QBUI
    ˖ S@USFF@DPNQJMF
    ˖ NBUDI@FOUSZ@DSFBUF NBUDI@FOUSZ@GSFF
    ˖ S@USFF@NBUDI@SPVUF

    View Slide

  121. What is Omissible
    ˖ match_entry_create match_entry_free
    ˖ 0OMZSFRVJSFEXIFO
    ˖ 6TF)551NFUIPEDPOEJUJPO
    ˖ $BQUVSFBSHVNFOU

    View Slide

  122. So
    ˖ *DBOPNJUUIFTFNFUIPETXIFOOPUOFDFTTBSZ

    View Slide

  123. Route req/s
    director ~2200
    node-r3 0.0.1 ~1900
    node-r3 0.0.3 ~5000
    node-r3 0.1.0 7800~10600 Not Yet

    View Slide

  124. ˖ "GUFSTPMWFTFDPOEJTTVF
    ˖ 8FIBWFGBTUFSOPEFS
    ˖ #VUJUDBOOPUQBTTQSFTTVSFUFTU
    ˖ %BUBJOEFYCFDPNFTSBOEPNOVNCFS BOEDSBTI
    BGUFSNPSFSFRVFTU

    View Slide

  125. ㉏겗
    Crash…

    View Slide

  126. View Slide

  127. View Slide

  128. Hard To Find The Bug

    View Slide

  129. var Router = function (routes) {!
    var route, data, method, route_frag, i = 0;!
    this.tree = libr3.r3_tree_create(10);!
    this.data = [];!
    for (route in routes) {!
    this.data[i] = routes[route];!
    data = ref.alloc('int', i);!
    route = route.trim();!
    route_frag = route.split(' ');!
    if (route_frag.length > 1) {!
    route = route_frag[1];!
    method = METHODS[route_frag[0].toUpperCase()];!
    if (!method) { throw new Error(route_frag[0]); }!
    r3_tree_insert_route(this.tree, method, route, data);!
    } else {!
    r3_tree_insert_route(this.tree, 0, route, data);!
    }!
    i++;!
    }!
    libr3.r3_tree_compile(this.tree);!
    return this;!
    };

    View Slide

  130. var Router = function (routes) {!
    var route, data, method, route_frag, i = 0;!
    this.tree = libr3.r3_tree_create(10);!
    this.data = [];!
    for (route in routes) {!
    this.data[i] = routes[route];!
    data = ref.alloc('int', i);!
    route = route.trim();!
    route_frag = route.split(' ');!
    if (route_frag.length > 1) {!
    route = route_frag[1];!
    method = METHODS[route_frag[0].toUpperCa
    if (!method) { throw new Error(route_fra
    r3_tree_insert_route(this.tree, method,
    } else {!
    r3_tree_insert_route(this.tree, 0, route
    }!
    i++;!
    }!
    libr3.r3_tree_compile(this.tree);!
    return this;!
    };
    WBSJBCMFT

    View Slide

  131. var Router = function (routes) {!
    var route, data, method, route_frag, i = 0;!
    this.tree = libr3.r3_tree_create(10);!
    this.data = [];!
    for (route in routes) {!
    this.data[i] = routes[route];!
    data = ref.alloc('int', i);!
    route = route.trim();!
    route_frag = route.split(' ');!
    if (route_frag.length > 1) {!
    route = route_frag[1];!
    method = METHODS[route_frag[0].toUpperCa
    if (!method) { throw new Error(route_fra
    r3_tree_insert_route(this.tree, method,
    } else {!
    r3_tree_insert_route(this.tree, 0, route
    }!
    i++;!
    }!
    libr3.r3_tree_compile(this.tree);!
    return this;!
    };
    DSFBUFUSFF

    View Slide

  132. var Router = function (routes) {!
    var route, data, method, route_frag, i = 0;!
    this.tree = libr3.r3_tree_create(10);!
    this.data = [];!
    for (route in routes) {!
    this.data[i] = routes[route];!
    data = ref.alloc('int', i);!
    route = route.trim();!
    route_frag = route.split(' ');!
    if (route_frag.length > 1) {!
    route = route_frag[1];!
    method = METHODS[route_frag[0].toUpperCa
    if (!method) { throw new Error(route_fra
    r3_tree_insert_route(this.tree, method,
    } else {!
    r3_tree_insert_route(this.tree, 0, route
    }!
    i++;!
    }!
    libr3.r3_tree_compile(this.tree);!
    return this;!
    };
    EBUBTUPSBHF

    View Slide

  133. var Router = function (routes) {!
    var route, data, method, route_frag, i = 0;!
    this.tree = libr3.r3_tree_create(10);!
    this.data = [];!
    for (route in routes) {!
    this.data[i] = routes[route];!
    data = ref.alloc('int', i);!
    route = route.trim();!
    route_frag = route.split(' ');!
    if (route_frag.length > 1) {!
    route = route_frag[1];!
    method = METHODS[route_frag[0].toUpperCa
    if (!method) { throw new Error(route_fra
    r3_tree_insert_route(this.tree, method,
    } else {!
    r3_tree_insert_route(this.tree, 0, route
    }!
    i++;!
    }!
    libr3.r3_tree_compile(this.tree);!
    return this;!
    };
    QBSTFSPVUFT

    View Slide

  134. var Router = function (routes) {!
    var route, data, method, route_frag, i = 0;!
    this.tree = libr3.r3_tree_create(10);!
    this.data = [];!
    for (route in routes) {!
    this.data[i] = routes[route];!
    data = ref.alloc('int', i);!
    route = route.trim();!
    route_frag = route.split(' ');!
    if (route_frag.length > 1) {!
    route = route_frag[1];!
    method = METHODS[route_frag[0].toUpperCa
    if (!method) { throw new Error(route_fra
    r3_tree_insert_route(this.tree, method,
    } else {!
    r3_tree_insert_route(this.tree, 0, route
    }!
    i++;!
    }!
    libr3.r3_tree_compile(this.tree);!
    return this;!
    };
    DSFBUFJOEFY

    View Slide

  135. var Router = function (routes) {!
    var route, data, method, route_frag, i = 0;!
    this.tree = libr3.r3_tree_create(10);!
    this.data = [];!
    for (route in routes) {!
    this.data[i] = routes[route];!
    data = ref.alloc('int', i);!
    route = route.trim();!
    route_frag = route.split(' ');!
    if (route_frag.length > 1) {!
    route = route_frag[1];!
    method = METHODS[route_frag[0].toUpperCa
    if (!method) { throw new Error(route_fra
    r3_tree_insert_route(this.tree, method,
    } else {!
    r3_tree_insert_route(this.tree, 0, route
    }!
    i++;!
    }!
    libr3.r3_tree_compile(this.tree);!
    return this;!
    };
    QBSTFTUSJOH

    View Slide

  136. var Router = function (routes) {!
    var route, data, method, route_frag, i = 0;!
    this.tree = libr3.r3_tree_create(10);!
    this.data = [];!
    for (route in routes) {!
    this.data[i] = routes[route];!
    data = ref.alloc('int', i);!
    route = route.trim();!
    route_frag = route.split(' ');!
    if (route_frag.length > 1) {!
    route = route_frag[1];!
    method = METHODS[route_frag[0].toUpperCa
    if (!method) { throw new Error(route_fra
    r3_tree_insert_route(this.tree, method,
    } else {!
    r3_tree_insert_route(this.tree, 0, route
    }!
    i++;!
    }!
    libr3.r3_tree_compile(this.tree);!
    return this;!
    };
    NFUIPEDPOEJUJPO

    View Slide

  137. var Router = function (routes) {!
    var route, data, method, route_frag, i = 0;!
    this.tree = libr3.r3_tree_create(10);!
    this.data = [];!
    for (route in routes) {!
    this.data[i] = routes[route];!
    data = ref.alloc('int', i);!
    route = route.trim();!
    route_frag = route.split(' ');!
    if (route_frag.length > 1) {!
    route = route_frag[1];!
    method = METHODS[route_frag[0].toUpperCa
    if (!method) { throw new Error(route_fra
    r3_tree_insert_route(this.tree, method,
    } else {!
    r3_tree_insert_route(this.tree, 0, route
    }!
    i++;!
    }!
    libr3.r3_tree_compile(this.tree);!
    return this;!
    };
    JOTFSUSPVUF

    View Slide

  138. var Router = function (routes) {!
    var route, data, method, route_frag, i = 0;!
    this.tree = libr3.r3_tree_create(10);!
    this.data = [];!
    for (route in routes) {!
    this.data[i] = routes[route];!
    data = ref.alloc('int', i);!
    route = route.trim();!
    route_frag = route.split(' ');!
    if (route_frag.length > 1) {!
    route = route_frag[1];!
    method = METHODS[route_frag[0].toUpperCa
    if (!method) { throw new Error(route_fra
    r3_tree_insert_route(this.tree, method,
    } else {!
    r3_tree_insert_route(this.tree, 0, route
    }!
    i++;!
    }!
    libr3.r3_tree_compile(this.tree);!
    return this;!
    };
    DPNQJMFUSFF

    View Slide

  139. Any Idea?

    View Slide

  140. var Router = function (routes) {!
    var route, data, method, route_frag, i = 0;!
    this.tree = libr3.r3_tree_create(10);!
    this.data = [];!
    for (route in routes) {!
    this.data[i] = routes[route];!
    data = ref.alloc('int', i);!
    route = route.trim();!
    route_frag = route.split(' ');!
    if (route_frag.length > 1) {!
    route = route_frag[1];!
    method = METHODS[route_frag[0].toUpperCase()];!
    if (!method) { throw new Error(route_frag[0]); }!
    r3_tree_insert_route(this.tree, method, route, data);!
    } else {!
    r3_tree_insert_route(this.tree, 0, route, data);!
    }!
    i++;!
    }!
    libr3.r3_tree_compile(this.tree);!
    return this;!
    };

    View Slide

  141. The Bug
    ˖ dataJTMPDBMWBSJBCMF
    ˖ 8JMMCFGSFFEVSJOH(BSCBHF$PMMFDUJPO

    View Slide

  142. var Router = function (routes) {!
    var route, data, method, route_frag, i = 0;!
    this.tree = libr3.r3_tree_create(10);!
    this.data = [];!
    this.index = [];!
    for (route in routes) {!
    this.data[i] = routes[route];!
    data = ref.alloc('int', i);!
    this.index[i] = data; // prevent GC!
    route = route.trim();!
    route_frag = route.split(' ');!
    if (route_frag.length > 1) {!
    route = route_frag[1];!
    method = METHODS[route_frag[0].toUpperCase()];!
    if (!method) { throw new Error(route_frag[0]); }!
    r3_tree_insert_route(this.tree, method, route, data);!
    } else {!
    r3_tree_insert_route(this.tree, 0, route, data);!
    }!
    i++;!
    }!
    libr3.r3_tree_compile(this.tree);!
    return this;!
    };

    View Slide

  143. 荈䊹涸隶侸荈䊹鎹
    鎹䖤+BWB4DSJQU剤($

    View Slide

  144. ˖ "GUFSTPMWFBMMJTTVFT
    ˖ 8FOBMMZIBWFBSFBMMZTUBCMF IJHIQFSGPSNBODF
    SPVUFSMJC
    ˖ "OEUIBUTSFMFBTF
    ˖ /PXJT

    View Slide

  145. node-r3

    View Slide

  146. var Router = require('node-r3').Router;!
    !
    var router = new Router({!
    "/foo": "data string",!
    "/foo/bar": function () {},!
    "/foo/bar/qoo": {obj: 1},!
    });!
    !
    var dispatched = router.match("/foo");!
    !
    router.free();

    View Slide

  147. var router = new Router({!
    "/": handler,!
    "/foo": fooHandler,!
    "/foo/{id}": fooHandler,!
    "POST /me": postMeHandler,!
    "GET /me": getMeHandler,!
    "POST|GET /post": postHandler,!
    });!
    !
    var server = http.createServer(!
    router.httpHandler(notfound)!
    );

    View Slide

  148. Handler Function
    function (req, res, captures)
    array

    View Slide

  149. Error Handler Function
    function (req, res)

    View Slide

  150. Known Issues
    ˖ .FNPSZMFBL
    ˖ 1FSGPSNBODFJNQSPWFNFOU

    View Slide

  151. Question?

    View Slide

  152. Thanks For your
    Attention

    View Slide