SlideShare uma empresa Scribd logo
1 de 53
[object Object]
Thierry GAYET - January 2012
Introduction
Official web site :  http://code.google.com/p/abus/ A-Bus is a lightweight message bus system, a simple way for embedded applications to talk to one another, merely in professional world, but not restricted to.  The message bus is built on top of a one-to-one message passing JSON-RPC framework.  There's no daemon involved in the message bus. Got trapped in the past with a clumsy inter process communication bus?  No sane alternative to propose as a replacement for a stinky legacy middle-ware?  It's now time to stop the hurting and get your chance to escape the wheel of reincarnation. ,[object Object]
DBUS ABUS UNIX SOCKETS ,[object Object],GNU/Linux kernel GNU/Linux kernel DBUS DAEMON libdbus libdbus binary1 binary1 libdbus libdbus binary1 binary1
This documentation is free; you can redistribute it without any restrictions. The modification or derived work must retain copyright and list all authors. This documentation is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Licence :  http://www.gnu.org/licenses/lgpl.html ,[object Object]
Maillist :  https://accounts.google.com/ServiceLogin?service=groups2&passive=1209600&continue=http://groups.google.com/group/abus-discuss&followup=http://groups.google.com/group/abus-discuss Abus issues :  http://code.google.com/p/abus/issues/list?can=1&q=&colspec=ID+Type+Status+Priority+Milestone+Owner+Summary&cells=tiles ,[object Object]
Build the abus library from sources
Get the latest abus source code from the subversion repository : $ svn checkout http://abus.googlecode.com/svn/trunk/ abus-read-only Then go into the directory: $ cd abus-read-only If you want to test abus over json-rpc call (for web purpose), you will need this package : $ sudo apt-get install libfcgi-dev  ,[object Object]
Abus support unitary test based on the google/test framework. You can install it on native GNU/linux such as :  $ sudo apt-get install libgtest-dev However, the google/test ”suck” with its autotools support, that's why we need to add a gtest.pc file in the following path : /usr/lib/pkgconfig/ with the following content : prefix=/usr exec_prefix=${prefix} libdir=${exec_prefix}/lib includedir=${prefix}/include Name: gtest Description: The google test framework Requires:  Version: 1.6.0 Libs: -lgtest -L${libdir} Cflags: -I${includedir}/gtest/ This file add metadata for the abus package. ,[object Object]
First we need to generate the intermediate autotools templates :  $ autoreconf -i --force That will generate: a Makefile.in  from the Makefile.am template a configure script and abus_config.h.in from the configure.ac template This is possible to see the configure usage: ./configure --help Configure the abus package : $ ./configure –prefix=/usr --enable-fcgi --enable-examples –enable-test  Build it :  $ make -j 5 Install it :  $ sudo make install or $ sudo make install DESTDIR=<INSTALL_PATH> Check your package using google/test framework : $ make check ← Everything must be in  green  (not  red ) ,[object Object]
/usr/include/abus.hpp /usr/include/jsonrpc.h /usr/include/json.h /usr/include/abus.h /usr/include/standard.h /usr/include/hashtab.h Headers : /usr/lib/pkgconfig /usr/lib/pkgconfig/abus.pc /usr/lib/libabus.la /usr/lib/libabus.so.0 /usr/lib/libabus.so /usr/lib/libabus.a /usr/lib/libabus.so.0.0.0 Libraries & meta-data : /usr/share/man/man1/abus-send.1 Online documentation :  /usr/bin/abus-send Tools :  ,[object Object]
Abus & autotools integration
Abus is fully compatible with recent autotools. That provide the possibility to interract easily with the abus library such as : (extract from a configure.ac template) (…) dnl -------------------------------------------- dnl Test if the libabus is well available in the stagingdir dnl If so get the cflags and ldflag from the .pc file dnl -------------------------------------------- LIBABUS_REQUIRED_VERSION=0.2~svn PKG_CHECK_MODULES([ABUS],[abus >= $LIBABUS_REQUIRED_VERSION],[have_abus=yes],[have_abus=no]) if test &quot;$have_libabus&quot; = no ; then   AC_MSG_ERROR([Missing libgtest library $LIBABUS_REQUIRED_VERSION (http://code.google.com/p/abus/) !!]) Fi (…) The above set the abus library as mandatory dependency. ,[object Object]
(extract from a Makefile.am template) (...) bin_PROGRAMS  =  myBin myBin _SOURCES = $(top_srcdir)/src/myBin.c     $(top_srcdir)/src/myBin.h myBin _CFLAG  = -I$(HEADER_DIR)  $(ABUS_CFLAGS) or myBin _CPPGLAGS = $(ABUS_CPPFLAGS)  or myBin _CXXGLAGS = $(ABUS_CXXFLAGS)  myBin _LDFLAGS =  myBin _LDADD  = $(ABUS_LIBS) ,[object Object]
The abus public API Header : abus.h
const   char  * abus_get_version (); const   char  * abus_get_copyright (); Global : int   abus_init ( abus_t  *abus); int   abus_cleanup ( abus_t  *abus); Initialization and clean an abus context int   abus_decl_method ( abus_t  *abus,  const   char  *service_name,  const   char  *method_name,  abus_callback_t  method_callback,  int  flags,  void  *arg,  const   char  *descr,  const   char  *fmt,  const   char  *result_fmt); int   abus_undecl_method ( abus_t  *abus,  const   char  *service_name,  const   char  *method_name); Declare and undeclare a method : int   abus_request_method_init ( abus_t  *abus,  const   char  *service_name,  const   char  *method_name, json_rpc_t *json_rpc); int   abus_request_method_invoke ( abus_t  *abus, json_rpc_t *json_rpc,  int  flags,  int  timeout); int   abus_request_method_cleanup ( abus_t  *abus, json_rpc_t *json_rpc); Synchronous calls : int   abus_request_method_invoke_async ( abus_t  *abus, json_rpc_t *json_rpc,  int  timeout,  abus_callback_t  callback,  int  flags,  void  *arg); int   abus_request_method_wait_async ( abus_t  *abus, json_rpc_t *json_rpc,  int  timeout); Asynchronous calls with callback : typedef   void  (* abus_callback_t )(json_rpc_t *json_rpc,  void  *arg); ,[object Object]
int   abus_decl_event ( abus_t  *abus,  const   char  *service_name,  const   char  *event_name,  const   char  *descr,  const   char  *fmt); int   abus_undecl_event ( abus_t  *abus,  const   char  *service_name,  const   char  *event_name); int   abus_request_event_init ( abus_t  *abus,  const   char  *service_name,  const   char  *event_name, json_rpc_t *json_rpc); int   abus_request_event_publish ( abus_t  *abus, json_rpc_t *json_rpc,  int  flags); int   abus_request_event_cleanup ( abus_t  *abus, json_rpc_t *json_rpc); int   abus_event_subscribe ( abus_t  *abus,  const   char  *service_name,  const   char  *event_name,  abus_callback_t  callback,  int  flags,  void  *arg,  int  timeout); int   abus_event_unsubscribe ( abus_t  * abus ,  const   char  *service_name,  const   char  *event_name,  abus_callback_t  callback,  void  *arg,  int  timeout); Publish and subscribe : int   abus_decl_attr_int ( abus_t  *abus,  const   char  *service_name,  const   char  *attr_name,  int  *val,  int  flags,  const   char  *descr); int   abus_decl_attr_bool ( abus_t  *abus,  const   char  *service_name,  const   char  *attr_name,  bool  *val,  int  flags,  const   char  *descr); int   abus_decl_attr_double ( abus_t  *abus,  const   char  *service_name,  const   char  *attr_name,  double  *val,  int  flags,  const   char  *descr); int   abus_decl_attr_str ( abus_t  *abus,  const   char  *service_name,  const   char  *attr_name,  char  *val, size_t n,  int  flags,  const   char  *descr); int   abus_undecl_attr ( abus_t  *abus,  const   char  *service_name,  const   char  *attr_name); int   abus_attr_changed ( abus_t  *abus,  const   char  *service_name,  const   char  *attr_name); int   abus_append_attr ( abus_t  *abus, json_rpc_t *json_rpc,  const   char  *service_name,  const   char  *attr_name); Attributes/data model service side : int   abus_attr_get_int ( abus_t  *abus,  const   char  *service_name,  const   char  *attr_name,  int  *val,  int  timeout); int   abus_attr_get_bool ( abus_t  *abus,  const   char  *service_name,  const   char  *attr_name,  bool  *val,  int  timeout); int   abus_attr_get_double ( abus_t  *abus,  const   char  *service_name,  const   char  *attr_name,  double  *val,  int  timeout); int   abus_attr_get_str ( abus_t  *abus,  const   char  *service_name,  const   char  *attr_name,  char  *val, size_t n,  int  timeout); Attributes/data model client side : ,[object Object]
int   abus_attr_set_int ( abus_t  *abus,  const   char  *service_name,  const   char  *attr_name,  int  val,  int  timeout); int   abus_attr_set_bool ( abus_t  *abus,  const   char  *service_name,  const   char  *attr_name,  bool  val,  int  timeout); int   abus_attr_set_double ( abus_t  *abus,  const   char  *service_name,  const   char  *attr_name,  double  val,  int  timeout); int   abus_attr_set_str ( abus_t  *abus,  const   char  *service_name,  const   char  *attr_name,  const   char  *val,  int  timeout); int   abus_attr_subscribe_onchange ( abus_t  *abus,  const   char  *service_name,  const   char  *attr_name,  abus_callback_t  callback,  int  flags,  void  *arg,  int  timeout); int   abus_attr_unsubscribe_onchange ( abus_t  *abus,  const   char  *service_name,  const   char  *attr_name,  abus_callback_t  callback,  void  *arg,  int  timeout); int   abus_forward_rpc ( abus_t  *abus,  char  *buffer,  int  *buflen,  int  flags,  int  timeout); Fast/CGI helper : Latest API available here :  http://abus.googlecode.com/svn/doc/HEAD/html/index.html ,[object Object]
The libjson public API Header : json.h
JSON WIKIPEDIA :  http://en.wikipedia.org/wiki/JSON JSON standard (RFC) : http://www.ietf.org/rfc/rfc4627 Validate a json file : http://jsonlint.com/ JSON beautifier : http://jsonformatter.bugz.fr/  JSON SCHEMA :  http://json-schema.org/ Official website :  http://www.json.org/ JSON, or  J ava S cript  O bject  N otation, is a lightweight text-based open standard designed for  human-readable  data interchange. It is derived from the  JavaScript  scripting language for representing simple  data structures  and  associative arrays , called objects. Despite its relationship to JavaScript, it is language-independent, with parsers available for most languages. The JSON format was originally specified by  Douglas Crockford , and is described in  RFC 4627 . The official  Internet media type  for JSON is application/json. The JSON filename extension is .json. The JSON format is often used for  serializing  and transmitting structured data over a network connection. It is used primarily to transmit data between a server and web application, serving as an alternative to  XML . ,[object Object]
{ &quot;firstName&quot;: &quot;John&quot;, &quot;lastName&quot; : &quot;Smith&quot;, &quot;age&quot;  : 25, &quot;address&quot;  : { &quot;streetAddress&quot;: &quot;21 2nd Street&quot;, &quot;city&quot;  : &quot;New York&quot;, &quot;state&quot;  : &quot;NY&quot;, &quot;postalCode&quot;  : &quot;10021&quot; }, &quot;phoneNumber&quot;: [ { &quot;type&quot;  : &quot;home&quot;, &quot;number&quot;: &quot;212 555-1234&quot; }, { &quot;type&quot;  : &quot;fax&quot;, &quot;number&quot;: &quot;646 555-4567&quot; } ] } Exemple of JSON :  ,[object Object]
[object Object]
[object Object]
Get the parent's node : Some function have been implemented to the libjson : json_dom_val_t *  json_config_open ( const   char * szJsonFilename); void   json_config_cleanup ( json_dom_val_t * element); json_dom_val_t *  json_config_lookup ( json_dom_val_t * element,  const   char * szDirectoryNane); int   json_config_get_int ( json_dom_val_t * element,  int * val); Extract a node content by type : int   json_config_get_bool ( json_dom_val_t * element,  bool * val); int   json_config_get_string ( json_dom_val_t * element,  char ** val); int   json_config_get_double ( json_dom_val_t * element,  double * val); Locate a node and extract its content by type : int   json_config_get_direct_int ( json_dom_val_t * root,  const   char * directoryName,  const   char * attributeName,  int * val); bool   json_config_get_direct_bool ( json_dom_val_t * root,  const   char * directoryName,  const   char * attributeName,  bool * val); int   json_config_get_direct_string ( json_dom_val_t * root,  const   char * directoryName,  const   char * attributeName,  char ** val); int   json_config_get_direct_double ( json_dom_val_t * root,  const   char * directoryName,  const   char * attributeName,  double * val); ,[object Object]
int  main( int  argc,  char * argv[],  char * env[]) { int   ret = -1; char *   valItem  = NULL; char * valItem2 = NULL; char * valItem3 = NULL; json_dom_val_t* json_dom  = NULL; json_dom_val_t* myParentItem = NULL; json_dom_val_t* myItem = NULL; /* Load and parse the  json  file */ if  (argc >=2) { if  ( NULL != (json_dom = json_config_open(argv[1]))) { printf( &quot; [DBG] JSON  init  and converted into a DOM : OK &quot; ); printf( &quot; [DBG] Looking for the parent item ('result') . . .&quot; ); /* --------------------------------------------------------- */ /* First example  */ /* --------------------------------------------------------- */ if  (NULL != (myParentItem = json_config_lookup(json_dom,  &quot;networking&quot; ))) { printf( &quot; [DBG] Parent item 'networking' (%p) well found&quot; , myParentItem); if  (NULL != (myItem = json_config_lookup(myParentItem,  &quot; ipaddress &quot; ))) { printf( &quot; [DBG] Child item ' ipaddress ' (%p) well found &quot; , myItem); if  (-1 != (ret = json_config_get_string(myItem, &valItem))) printf( &quot; [DBG] Item's value = '%s' &quot; , valItem); else printf( &quot; [ERROR] Problem to get the item's value &quot; ); }  else  { printf( &quot; [ERROR] Child item not found &quot; ); }  /* IF */ ,[object Object]
if  (NULL != (myItem = json_config_lookup(myParentItem,  &quot;gateway&quot; ))) { printf( &quot; [DBG] Child item 'gateway' (%p) well found &quot; , myItem); if  (-1 != (ret = json_config_get_string(myItem, &valItem2))) printf( &quot; [DBG] Item's value = '%s' &quot; , valItem2); else printf( &quot; [ERROR] Problem to get the item's value &quot; ); }  else  { printf( &quot; [ERROR] Child item not found &quot; ); }  /* IF */ }  else  { printf( &quot; [ERROR] Parent item not found &quot; ); }  /* IF */ /* --------------------------------------------------------- */ /* Second example  */ /* --------------------------------------------------------- */ json_config_get_direct_string(json_dom,  &quot;networking&quot; ,  &quot; ipaddress &quot; , &valItem3); printf( &quot; [DBG] Item's value = '%s' &quot; , valItem3); /* Cleaning the  dom  */ if  (NULL != json_dom) json_config_cleanup(json_dom); }  else  { printf( &quot; [ERROR] JSON  init  and converted into a DOM : NOK &quot; ); }  /* IF */ printf( &quot;&quot; ); }  else  { printf( &quot; [ERROR] Expected parameter to %s !!&quot; , argv[0]); printf( &quot; [ERROR] Usage: %s <json file> &quot; , argv[0]); }  /* IF */ return (ret); } ,[object Object]
Roadmap : - extension with datamodel request ,[object Object]
local unix sockets First example : simple service and client libabus libabus libabus client service
#include <stdlib.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <errno.h> #include &quot;abus.h&quot; /* Main function */ int main(int argc, char **argv) {   /* Declare the abus context */ abus_t abus;   /* Initialize the abus context */ abus_init (&abus);   /* Register a first method */ abus_decl_method (&abus, &quot;examplesvc&quot;, &quot;sum&quot;, &svc_sum_cb, ABUS_RPC_FLAG_NONE, &quot;sumator cookie&quot;, &quot;Compute summation of two integers&quot;, &quot;a:i:first operand,b:i:second operand&quot;, &quot;res_value:i:summation&quot;);   /* Register another methode */ abus_decl_method (&abus, &quot;examplesvc&quot;, &quot;mult&quot;, &svc_mult_cb, ABUS_RPC_FLAG_NONE, &quot;multiply cookie&quot;, &quot;Compute multiplication of two integers&quot;, &quot;a:i:first operand,b:i:second operand&quot;, &quot;res_value:i:multiplication&quot;); /* do other stuff */ sleep(10000);   /* Clean the abus context – it unregister all methods */ abus_cleanup (&abus);   /* Exit the main function and provide a return code */ return EXIT_SUCCESS; } example-service.c ,[object Object]
static void  svc_sum_cb (json_rpc_t *json_rpc, void *arg) { int a, b; int ret; ret  =  json_rpc_get_int (json_rpc, &quot;a&quot;, &a); if (ret == 0) ret =  json_rpc_get_int (json_rpc, &quot;b&quot;, &b); printf(&quot;## %s: arg=%s, ret=%d, a=%d, b=%d, => result=%d&quot;, __func__, (const char*)arg, ret, a, b, a+b); if (ret) json_rpc_set_error (json_rpc, ret, NULL); else json_rpc_append_int (json_rpc, &quot;res_value&quot;, a+b); } static void  svc_mult_cb (json_rpc_t *json_rpc, void *arg) { int a, b; int ret; ret  =  json_rpc_get_int (json_rpc, &quot;a&quot;, &a); if (ret == 0) ret =  json_rpc_get_int (json_rpc, &quot;b&quot;, &b); printf(&quot;## %s: arg=%s, ret=%d, a=%d, b=%d, => result=%d&quot;, __func__, (const char*)arg, ret, a, b, a*b);   if (ret) json_rpc_set_error (json_rpc, ret, NULL); else json_rpc_append_int (json_rpc, &quot;res_value&quot;, a*b); } example-service.c ,[object Object]
#include <stdlib.h> #include <stdio.h> #include <string.h> #include <errno.h> #include &quot;abus.h&quot; #define RPC_TIMEOUT 1000 /* in ms */ int main(int argc, char **argv) { abus_t  abus; json_rpc_t json_rpc; int  ret;   Int  res_value; const char *service_name = &quot;examplesvc&quot;; if (argc < 4) { printf(&quot;usage: %s METHOD firstvalue secondvalue&quot;, argv[0]); exit(EXIT_FAILURE); } abus_init (&abus); /* method name is taken from command line */ ret =  abus_request_method_init (&abus, service_name, argv[1], &json_rpc); if (ret) exit(EXIT_FAILURE); /* pass 2 parameters: &quot;a&quot; and &quot;b&quot; */ json_rpc_append_int (&json_rpc, &quot;a&quot;, atoi(argv[2])); json_rpc_append_int (&json_rpc, &quot;b&quot;, atoi(argv[3])); example-client.c ,[object Object]
ret =  abus_request_method_invoke (&abus, &json_rpc, ABUS_RPC_FLAG_NONE, RPC_TIMEOUT); if (ret != 0) { printf(&quot;RPC failed with error %d&quot;, ret); exit(EXIT_FAILURE); } ret =  json_rpc_get_int (&json_rpc, &quot;res_value&quot;, &res_value); if (ret == 0) printf(&quot;res_value=%d&quot;, res_value); else printf(&quot;No result? error %d&quot;, ret); abus_request_method_cleanup (&abus, &json_rpc); abus_cleanup (&abus); return EXIT_SUCCESS; } example-client.c ,[object Object]
local unix sockets Second example : working with array libabus libabus libabus client service
#include <stdlib.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <errno.h> #include &quot;abus.h&quot; static void svc_array_sqr_cb(json_rpc_t *json_rpc, void *arg) { int k, a; int ret, count, i; int *ary = NULL; ret =  json_rpc_get_int (json_rpc, &quot;k&quot;, &k); if (ret != 0) { json_rpc_set_error (json_rpc, ret, NULL); return; } count =  json_rpc_get_array_count (json_rpc, &quot;my_array&quot;); if (count >= 0) { /* first put all the values in an array, in order to not mix json_rpc_get's and json_rpc_append's for readability sake */ ary = malloc(count*sizeof(int)); for (i = 0; i<count; i++) { /* Aim at i-th element within array &quot;my_array&quot; */ ret =  json_rpc_get_point_at (json_rpc, &quot;my_array&quot;, i); if (ret != 0) break; /* from that dictionary, get parameter &quot;a&quot; * Rem: expects all array elements to contain at least a param &quot;a&quot; */ ret =  json_rpc_get_int (json_rpc, &quot;a&quot;, &ary[i]); if (ret != 0) break; } } example-svc-array.c ,[object Object]
printf(&quot;## %s: arg=%s, ret=%d, k=%d, array count=%d&quot;, __func__, (const char*)arg, ret, k, count); if (ret) { json_rpc_set_error (json_rpc, ret, NULL); } else { json_rpc_append_int (json_rpc, &quot;res_k&quot;, k); /* begin the array */ json_rpc_append_args (json_rpc, JSON_KEY, &quot;res_array&quot;, -1, JSON_ARRAY_BEGIN, -1); for (i = 0; i<count; i++) { /* each array element *must* be an &quot;OBJECT&quot;, i.e. a dictonary */ json_rpc_append_args (json_rpc, JSON_OBJECT_BEGIN, -1); json_rpc_append_int (json_rpc, &quot;res_a&quot;, ary[i]*ary[i]); /* more stuff may be appended in there */ json_rpc_append_args (json_rpc, JSON_OBJECT_END, -1); } /* end the array */ json_rpc_append_args (json_rpc, JSON_ARRAY_END, -1); } if (ary) free(ary); } example-svc-array.c ,[object Object]
int main(int argc, char **argv) { abus_t abus; abus_init (&abus); abus_decl_method (&abus, &quot;examplearraysvc&quot;, &quot;sqr&quot;, &svc_array_sqr_cb, ABUS_RPC_FLAG_NONE, &quot;square cookie&quot;, &quot;Compute square value of all the elements of an array. Serves as an example of how to deal with array in A-Bus&quot;, &quot;k:i:some contant,my_array:(a:i:value to be squared,arg_index:i:index of arg for demo):array of stuff&quot;, &quot;res_k:i:same contant,res_array:(res_a:i:squared value):array of squared stuff&quot;); /* do other stuff */ sleep(10000); abus_cleanup (&abus); return EXIT_SUCCESS; } example-svc-array.c ,[object Object]
example-clnt-array.c #include <stdlib.h> #include <stdio.h> #include <string.h> #include <errno.h> #include &quot;abus.h&quot; #define RPC_TIMEOUT 1000 /* ms */ int main(int argc, char **argv) { abus_t abus; json_rpc_t json_rpc; int count, i, ret, res_value; const char *service_name = &quot;examplearraysvc&quot;; if (argc < 4) { printf(&quot;usage: %s METHOD k values...&quot;, argv[0]); exit(EXIT_FAILURE); } abus_init (&abus); /* method name is taken from command line */ ret =  abus_request_method_init (&abus, service_name, argv[1], &json_rpc); if (ret) exit(EXIT_FAILURE); /* pass 2 parameters: &quot;k&quot; and &quot;my_array&quot; */ json_rpc_append_int (&json_rpc, &quot;k&quot;, atoi(argv[2])); /* begin the array */ json_rpc_append_args (&json_rpc, JSON_KEY, &quot;my_array&quot;, -1, JSON_ARRAY_BEGIN, -1); ,[object Object]
example-clnt-array.c   ret =  abus_request_method_invoke (&abus, &json_rpc, ABUS_RPC_FLAG_NONE, RPC_TIMEOUT); if (ret != 0) { printf(&quot;RPC failed with error %d&quot;, ret); exit(EXIT_FAILURE); } count =  json_rpc_get_array_count (&json_rpc, &quot;res_array&quot;); if (count < 0) { printf(&quot;No result? error %d&quot;, count); exit(EXIT_FAILURE); } ret =  json_rpc_get_int (&json_rpc, &quot;res_k&quot;, &res_value); if (ret == 0) printf(&quot;res_k=%d&quot;, res_value); else printf(&quot;No result? error %d&quot;, ret); for (i = 0; i<count; i++)  { /* Aim at i-th element within array &quot;res_array&quot; */ json_rpc_get_point_at (&json_rpc, &quot;res_array&quot;, i); printf(&quot;res_array[%d]&quot;, i); ret =  json_rpc_get_int (&json_rpc, &quot;res_a&quot;, &res_value); if (ret == 0) printf(&quot;res_a=%d&quot;, res_value); else printf(&quot;No result? error %d&quot;, ret); } ,[object Object]
example-clnt-array.c /* Aim back out of array */ json_rpc_get_point_at (&json_rpc, NULL, i); ret =  json_rpc_get_int (&json_rpc, &quot;res_k&quot;, &res_value); if (ret == 0) printf(&quot;res_k=%d (should be the same as previously)&quot;, res_value); else printf(&quot;No result? error %d&quot;, ret);   abus_request_method_cleanup (&abus, &json_rpc); abus_cleanup (&abus); return EXIT_SUCCESS; } ,[object Object]
local unix sockets Third example : exporting objects  libabus libabus libabus client service
This example is a service named &quot;exampleattrsvc&quot; written in C, dealing with attributes in a data model. To be used with the client example-clnt-attr. You may also use the abus-send program to test it: abus-send exampleattrsvc.get tree.some_int abus-send exampleattrsvc.get tree. abus-send exampleattrsvc.set tree.some_int:i:128 abus-send exampleattrsvc.get &quot;&quot; Here is how to play with event emitted upon attribute change (one event every 5 seconds): abus-send exampleattrsvc.subscribe attr_changed%tree.auto_count ,[object Object]
example-svc-attr.c #include <stdlib.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <errno.h> #include &quot;abus.h&quot; int main(int argc, char **argv) { abus_t abus; const char *servicename = &quot;exampleattrsvc&quot;; int i; int my_int = 42; int my_other_int = -2; int my_auto_count = 0; abus_init (&abus); abus_decl_attr_int (&abus, servicename, &quot;tree.some_int&quot;, &my_int, ABUS_RPC_FLAG_NONE, &quot;Some integer, for demo purpose&quot;); abus_decl_attr_int (&abus, servicename, &quot;tree.some_other_int&quot;, &my_other_int, ABUS_RPC_FLAG_NONE, &quot;Some other integer, still for demo purpose&quot;); abus_decl_attr_int (&abus, servicename, &quot;tree.auto_count&quot;, &my_auto_count, ABUS_RPC_FLAG_NONE, &quot;Counter incremented every 5 seconds&quot;); /* do other stuff */ for (i = 0; i < 1000; i++)  { sleep(5); my_auto_count++; /* trigger event notification */ abus_attr_changed (&abus, servicename, &quot;tree.auto_count&quot;); } abus_cleanup (&abus); return EXIT_SUCCESS; } ,[object Object]
example-clnt-attr.c #include <stdlib.h> #include <stdio.h> #include <string.h> #include <errno.h> #include &quot;abus.h&quot; #define RPC_TIMEOUT 1000 /* ms */ int main(int argc, char **argv) { abus_t abus; json_rpc_t json_rpc; int ret; const char *service_name = &quot;exampleattrsvc&quot;; const char *attr_name; int my_int; if (argc < 2) { printf(&quot;usage: %s ATTR newintegervalue&quot;, argv[0]); printf(&quot;usage: ATTR: some_int|some_other_int&quot;, argv[0]); exit(EXIT_FAILURE); } abus_init (&abus); /* attr name is taken from command line */ attr_name = argv[1]; ret =  abus_attr_get_int (&abus, service_name, attr_name, &my_int, RPC_TIMEOUT); if (ret) { printf(&quot;RPC failed with error %d&quot;, ret); abus_cleanup (&abus); exit(EXIT_FAILURE); } ,[object Object]
example-clnt-attr.c printf(&quot;Previous value: %s=%d&quot;, attr_name, my_int); my_int = atoi(argv[2]); ret =  abus_attr_set_int (&abus, service_name, attr_name, my_int, RPC_TIMEOUT); if (ret) { printf(&quot;RPC failed with error %d&quot;, ret); abus_cleanup (&abus); exit(EXIT_FAILURE); } printf(&quot;New value: %s=%d&quot;, attr_name, my_int); abus_cleanup (&abus); return EXIT_SUCCESS; } ,[object Object]
local unix sockets Fourth example : working with event libabus libabus libabus client service
example-svc-event.c #include <stdlib.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <errno.h> #include &quot;abus.h&quot; static void chomp(char *s) { int len = strlen(s); if (len > 0 && s[len-1] == '') s[len-1] = ''; } int main(int argc, char **argv) { abus_t abus; char s[128]; abus_init (&abus); #define MYSVCNAME &quot;examplesvc&quot; #define MYEVTNAME &quot;enter_pressed&quot; abus_decl_event (&abus, MYSVCNAME, MYEVTNAME, &quot;Event sent each time the ENTER key is press. Serves as publish/subscribe example.&quot;, &quot;typed_char:s:keys pressed before the ENTER key&quot;); /* cheap event generator: press ENTER key on stdin Attached to the event, the chars typed in before the ENTER key */ while (fgets(s, sizeof(s), stdin) != NULL) { json_rpc_t json_rpc; chomp(s); abus_request_event_init (&abus, MYSVCNAME, MYEVTNAME, &json_rpc); json_rpc_append_str(&json_rpc, &quot;typed_char&quot;, s); abus_request_event_publish (&abus, &json_rpc, 0); abus_request_event_cleanup (&abus, &json_rpc); } abus_cleanup (&abus); return EXIT_SUCCESS; } ,[object Object]
http://abus.googlecode.com/svn/doc/HEAD/html/examples.html More example available here : ,[object Object]
Advance abus
abus-send [options] SERVICE.METHOD [key:[bfilsae]]=value]... -h, --help  this help message -t, --timeout=TIMEOUT  timeout in milliseconds (1000) -v, --verbose  verbose -V, --version  version of A-Bus -y, --async  asynchronous query -w, --wait-async  wait for asynchronous query, without callback Some examples: Global introspection: abus-send myAbusService. Calling a method without parameters: abus-send myAbusService.getDeviceState Calling a method with parameters: abus-send myAbusService.setDeviceState   newState:b=false Getting an object: abus-send myAbusService.get deviceinfo. abus-send myAbusService.get &quot;&quot; ,[object Object]
An abus-monitor should come in the future. ,[object Object]
If you want that the libabus dump the json messages to stdout, you just have to export a variable :  export ABUS_MSG_VERBOSE=1 That will generate such trace: ##  4067 <- 00083:70 {&quot;jsonrpc&quot;:&quot;2.0&quot;,&quot;method&quot;:&quot;DmngCoreStub.getConfig&quot;,&quot;id&quot;:1,&quot;params&quot;:{}} ##  4067 -> 00083:2220 {&quot;jsonrpc&quot;:&quot;2.0&quot;,&quot;result&quot;:{&quot;device.stateID&quot;:false,&quot;device.actionID&quot;:0,&quot;device.languageID&quot;:0,&quot;device.uptime&quot;:742,&quot;mainPower.isPowerConnected&quot;:0,&quot;mainPower.batteryLevel&quot;:41,&quot;audio.ModeID&quot;:1,&quot;audio.BitRate&quot;:64,&quot;video.ModeType&quot;:0,&quot;video.BitRate&quot;:44,&quot;video.Frequency&quot;:0,&quot;liveProfile&quot;:[{&quot;id&quot;:0,&quot;name&quot;:&quot;INTERVIEW&quot;,&quot;rate&quot;:12,&quot;modeID&quot;:0,&quot;studioID&quot;:0,&quot;resolutionID&quot;:0,&quot;videoInputID&quot;:0,&quot;delay&quot;:12},{&quot;id&quot;:1,&quot;name&quot;:&quot;BALANCED&quot;,&quot;rate&quot;:5,&quot;modeID&quot;:1,&quot;studioID&quot;:4,&quot;resolutionID&quot;:1,&quot;videoInputID&quot;:1,&quot;delay&quot;:14},{&quot;id&quot;:2,&quot;name&quot;:&quot;QUALITY&quot;,&quot;rate&quot;:6,&quot;modeID&quot;:1,&quot;studioID&quot;:3,&quot;resolutionID&quot;:0,&quot;videoInputID&quot;:2,&quot;delay&quot;:20},{&quot;id&quot;:3,&quot;name&quot;:&quot;LOW DELAY&quot;,&quot;rate&quot;:4,&quot;modeID&quot;:1,&quot;studioID&quot;:2,&quot;resolutionID&quot;:0,&quot;videoInputID&quot;:1,&quot;delay&quot;:5},{&quot;id&quot;:4,&quot;name&quot;:&quot;BGAN&quot;,&quot;rate&quot;:2,&quot;modeID&quot;:0,&quot;studioID&quot;:0,&quot;resolutionID&quot;:1,&quot;videoInputID&quot;:2,&quot;delay&quot;:10}],&quot;studioListing&quot;:[{&quot;studioId&quot;:0,&quot;name&quot;:&quot;studio1&quot;,&quot;ipAddress&quot;:&quot;&quot;,&quot;channel&quot;:2,&quot;controlLink&quot;:true},{&quot;studioId&quot;:1,&quot;name&quot;:&quot;studio2&quot;,&quot;ipAddress&quot;:&quot;&quot;,&quot;channel&quot;:4,&quot;controlLink&quot;:false},{&quot;studioId&quot;:2,&quot;name&quot;:&quot;studio3&quot;,&quot;ipAddress&quot;:&quot;&quot;,&quot;channel&quot;:1,&quot;controlLink&quot;:true},{&quot;studioId&quot;:3,&quot;name&quot;:&quot;studio4&quot;,&quot;ipAddress&quot;:&quot;&quot;,&quot;channel&quot;:3,&quot;controlLink&quot;:true}],&quot;massstorageListing&quot;:[{&quot;id&quot;:0,&quot;devname&quot;:&quot;/dev/sda1&quot;,&quot;label&quot;:&quot;toto&quot;,&quot;uuid&quot;:&quot;110E8400-E29B-11D4-A716-446655440000&quot;,&quot;mountPoint&quot;:&quot;/tmp/disk1&quot;,&quot;totalSize&quot;:5000000,&quot;freeSize&quot;:500000,&quot;filesystem&quot;:39,&quot;type&quot;:0,&quot;isWrite&quot;:true},{&quot;id&quot;:1,&quot;devname&quot;:&quot;/dev/sda2&quot;,&quot;label&quot;:&quot;&quot;,&quot;uuid&quot;:&quot;550e8400-e29b-41d4-a716-446655440000&quot;,&quot;mountPoint&quot;:&quot;/tmp/disk2&quot;,&quot;totalSize&quot;:2000000,&quot;freeSize&quot;:20000,&quot;filesystem&quot;:39,&quot;type&quot;:1,&quot;isWrite&quot;:false}],&quot;networkinterfaceListing&quot;:[{&quot;id&quot;:0,&quot;status&quot;:1,&quot;mode&quot;:0,&quot;type&quot;:0,&quot;tx&quot;:30,&quot;rx&quot;:6,&quot;bandwitch&quot;:3,&quot;ifname&quot;:&quot;eth0&quot;,&quot;ipAddress&quot;:&quot;192.168.0.5&quot;,&quot;netmask&quot;:&quot;255.255.255.0&quot;,&quot;gateway&quot;:&quot;192.168.0.1&quot;},{&quot;id&quot;:1,&quot;status&quot;:1,&quot;mode&quot;:1,&quot;type&quot;:0,&quot;tx&quot;:26,&quot;rx&quot;:1,&quot;bandwitch&quot;:10,&quot;ifname&quot;:&quot;eth1&quot;,&quot;ipAddress&quot;:&quot;192.168.2.4&quot;,&quot;netmask&quot;:&quot;255.255.255.0&quot;,&quot;gateway&quot;:&quot;192.168.0.1&quot;},{&quot;id&quot;:2,&quot;status&quot;:1,&quot;mode&quot;:1,&quot;type&quot;:0,&quot;tx&quot;:19,&quot;rx&quot;:30,&quot;bandwitch&quot;:27,&quot;ifname&quot;:&quot;eth2&quot;,&quot;ipAddress&quot;:&quot;10.11.133.4&quot;,&quot;netmask&quot;:&quot;255.255.0.0&quot;,&quot;gateway&quot;:&quot;10.11.133.1&quot;},{&quot;id&quot;:3,&quot;status&quot;:1,&quot;mode&quot;:1,&quot;type&quot;:1,&quot;tx&quot;:48,&quot;rx&quot;:14,&quot;bandwitch&quot;:14,&quot;ifname&quot;:&quot;ath0&quot;,&quot;ipAddress&quot;:&quot;192.168.0.8&quot;,&quot;netmask&quot;:&quot;255.255.255.0&quot;,&quot;gateway&quot;:&quot;192.168.0.1&quot;}]},&quot;id&quot;:1} ,[object Object]
Here are some points for the abus evolution in the nearest future : - event management for web purpose - some security For more detail :  http://code.google.com/p/abus/wiki/ABusNotes ,[object Object]

Mais conteúdo relacionado

Mais procurados

Introduction to Swift programming language.
Introduction to Swift programming language.Introduction to Swift programming language.
Introduction to Swift programming language.Icalia Labs
 
Swift Programming Language
Swift Programming LanguageSwift Programming Language
Swift Programming LanguageGiuseppe Arici
 
Swift Programming Language
Swift Programming LanguageSwift Programming Language
Swift Programming LanguageAnıl Sözeri
 
Advanced python
Advanced pythonAdvanced python
Advanced pythonEU Edge
 
Advanced Python, Part 2
Advanced Python, Part 2Advanced Python, Part 2
Advanced Python, Part 2Zaar Hai
 
ES2015 (ES6) Overview
ES2015 (ES6) OverviewES2015 (ES6) Overview
ES2015 (ES6) Overviewhesher
 
Introduction into ES6 JavaScript.
Introduction into ES6 JavaScript.Introduction into ES6 JavaScript.
Introduction into ES6 JavaScript.boyney123
 
Pig Introduction to Pig
Pig Introduction to PigPig Introduction to Pig
Pig Introduction to PigChris Wilkes
 
JavaScript 1 for high school
JavaScript 1 for high schoolJavaScript 1 for high school
JavaScript 1 for high schooljekkilekki
 
Hacking parse.y (RubyKansai38)
Hacking parse.y (RubyKansai38)Hacking parse.y (RubyKansai38)
Hacking parse.y (RubyKansai38)ujihisa
 
Funkcija, objekt, python
Funkcija, objekt, pythonFunkcija, objekt, python
Funkcija, objekt, pythonRobert Lujo
 
VIM for (PHP) Programmers
VIM for (PHP) ProgrammersVIM for (PHP) Programmers
VIM for (PHP) ProgrammersZendCon
 
Denis Lebedev, Swift
Denis  Lebedev, SwiftDenis  Lebedev, Swift
Denis Lebedev, SwiftYandex
 

Mais procurados (20)

Swift 2
Swift 2Swift 2
Swift 2
 
Vim Hacks
Vim HacksVim Hacks
Vim Hacks
 
Introduction to Swift programming language.
Introduction to Swift programming language.Introduction to Swift programming language.
Introduction to Swift programming language.
 
Swift Programming Language
Swift Programming LanguageSwift Programming Language
Swift Programming Language
 
Bash production guide
Bash production guideBash production guide
Bash production guide
 
Swift Programming Language
Swift Programming LanguageSwift Programming Language
Swift Programming Language
 
Developing iOS apps with Swift
Developing iOS apps with SwiftDeveloping iOS apps with Swift
Developing iOS apps with Swift
 
Advanced python
Advanced pythonAdvanced python
Advanced python
 
Advanced Python, Part 2
Advanced Python, Part 2Advanced Python, Part 2
Advanced Python, Part 2
 
Don't do this
Don't do thisDon't do this
Don't do this
 
Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6
 
ES2015 (ES6) Overview
ES2015 (ES6) OverviewES2015 (ES6) Overview
ES2015 (ES6) Overview
 
ES6 and BEYOND
ES6 and BEYONDES6 and BEYOND
ES6 and BEYOND
 
Introduction into ES6 JavaScript.
Introduction into ES6 JavaScript.Introduction into ES6 JavaScript.
Introduction into ES6 JavaScript.
 
Pig Introduction to Pig
Pig Introduction to PigPig Introduction to Pig
Pig Introduction to Pig
 
JavaScript 1 for high school
JavaScript 1 for high schoolJavaScript 1 for high school
JavaScript 1 for high school
 
Hacking parse.y (RubyKansai38)
Hacking parse.y (RubyKansai38)Hacking parse.y (RubyKansai38)
Hacking parse.y (RubyKansai38)
 
Funkcija, objekt, python
Funkcija, objekt, pythonFunkcija, objekt, python
Funkcija, objekt, python
 
VIM for (PHP) Programmers
VIM for (PHP) ProgrammersVIM for (PHP) Programmers
VIM for (PHP) Programmers
 
Denis Lebedev, Swift
Denis  Lebedev, SwiftDenis  Lebedev, Swift
Denis Lebedev, Swift
 

Destaque

Open Source Creativity
Open Source CreativityOpen Source Creativity
Open Source CreativitySara Cannon
 
Reuters: Pictures of the Year 2016 (Part 2)
Reuters: Pictures of the Year 2016 (Part 2)Reuters: Pictures of the Year 2016 (Part 2)
Reuters: Pictures of the Year 2016 (Part 2)maditabalnco
 
The impact of innovation on travel and tourism industries (World Travel Marke...
The impact of innovation on travel and tourism industries (World Travel Marke...The impact of innovation on travel and tourism industries (World Travel Marke...
The impact of innovation on travel and tourism industries (World Travel Marke...Brian Solis
 
Lightning Talk #9: How UX and Data Storytelling Can Shape Policy by Mika Aldaba
Lightning Talk #9: How UX and Data Storytelling Can Shape Policy by Mika AldabaLightning Talk #9: How UX and Data Storytelling Can Shape Policy by Mika Aldaba
Lightning Talk #9: How UX and Data Storytelling Can Shape Policy by Mika Aldabaux singapore
 
The Six Highest Performing B2B Blog Post Formats
The Six Highest Performing B2B Blog Post FormatsThe Six Highest Performing B2B Blog Post Formats
The Six Highest Performing B2B Blog Post FormatsBarry Feldman
 

Destaque (6)

Open Source Creativity
Open Source CreativityOpen Source Creativity
Open Source Creativity
 
Reuters: Pictures of the Year 2016 (Part 2)
Reuters: Pictures of the Year 2016 (Part 2)Reuters: Pictures of the Year 2016 (Part 2)
Reuters: Pictures of the Year 2016 (Part 2)
 
The impact of innovation on travel and tourism industries (World Travel Marke...
The impact of innovation on travel and tourism industries (World Travel Marke...The impact of innovation on travel and tourism industries (World Travel Marke...
The impact of innovation on travel and tourism industries (World Travel Marke...
 
Succession “Losers”: What Happens to Executives Passed Over for the CEO Job?
Succession “Losers”: What Happens to Executives Passed Over for the CEO Job? Succession “Losers”: What Happens to Executives Passed Over for the CEO Job?
Succession “Losers”: What Happens to Executives Passed Over for the CEO Job?
 
Lightning Talk #9: How UX and Data Storytelling Can Shape Policy by Mika Aldaba
Lightning Talk #9: How UX and Data Storytelling Can Shape Policy by Mika AldabaLightning Talk #9: How UX and Data Storytelling Can Shape Policy by Mika Aldaba
Lightning Talk #9: How UX and Data Storytelling Can Shape Policy by Mika Aldaba
 
The Six Highest Performing B2B Blog Post Formats
The Six Highest Performing B2B Blog Post FormatsThe Six Highest Performing B2B Blog Post Formats
The Six Highest Performing B2B Blog Post Formats
 

Semelhante a Abus at a glance

Боремся с NPE вместе с Kotlin, Павел Шацких СберТех
Боремся с NPE вместе с Kotlin, Павел Шацких СберТехБоремся с NPE вместе с Kotlin, Павел Шацких СберТех
Боремся с NPE вместе с Kotlin, Павел Шацких СберТехСбертех | SberTech
 
Implementing of classical synchronization problem by using semaphores
Implementing of classical synchronization problem by using semaphoresImplementing of classical synchronization problem by using semaphores
Implementing of classical synchronization problem by using semaphoresGowtham Reddy
 
C++ Interview Question And Answer
C++ Interview Question And AnswerC++ Interview Question And Answer
C++ Interview Question And AnswerJagan Mohan Bishoyi
 
C++ questions And Answer
C++ questions And AnswerC++ questions And Answer
C++ questions And Answerlavparmar007
 
Linux Kernel, tested by the Linux-version of PVS-Studio
Linux Kernel, tested by the Linux-version of PVS-StudioLinux Kernel, tested by the Linux-version of PVS-Studio
Linux Kernel, tested by the Linux-version of PVS-StudioPVS-Studio
 
Hooking signals and dumping the callstack
Hooking signals and dumping the callstackHooking signals and dumping the callstack
Hooking signals and dumping the callstackThierry Gayet
 
Effecient javascript
Effecient javascriptEffecient javascript
Effecient javascriptmpnkhan
 
in c languageTo determine the maximum string length, we need to .pdf
in c languageTo determine the maximum string length, we need to .pdfin c languageTo determine the maximum string length, we need to .pdf
in c languageTo determine the maximum string length, we need to .pdfstopgolook
 
C++11 - A Change in Style - v2.0
C++11 - A Change in Style - v2.0C++11 - A Change in Style - v2.0
C++11 - A Change in Style - v2.0Yaser Zhian
 
Crafting Beautiful CLI Applications in Ruby
Crafting Beautiful CLI Applications in RubyCrafting Beautiful CLI Applications in Ruby
Crafting Beautiful CLI Applications in RubyNikhil Mungel
 
1183 c-interview-questions-and-answers
1183 c-interview-questions-and-answers1183 c-interview-questions-and-answers
1183 c-interview-questions-and-answersAkash Gawali
 
Compiler Design and Construction COSC 5353Project Instructions -
Compiler Design and Construction COSC 5353Project Instructions -Compiler Design and Construction COSC 5353Project Instructions -
Compiler Design and Construction COSC 5353Project Instructions -LynellBull52
 
Unit 4
Unit 4Unit 4
Unit 4siddr
 
C programming language tutorial
C programming language tutorial C programming language tutorial
C programming language tutorial javaTpoint s
 
李建忠、侯捷设计模式讲义
李建忠、侯捷设计模式讲义李建忠、侯捷设计模式讲义
李建忠、侯捷设计模式讲义yiditushe
 
Writing a TSDB from scratch_ performance optimizations.pdf
Writing a TSDB from scratch_ performance optimizations.pdfWriting a TSDB from scratch_ performance optimizations.pdf
Writing a TSDB from scratch_ performance optimizations.pdfRomanKhavronenko
 

Semelhante a Abus at a glance (20)

Боремся с NPE вместе с Kotlin, Павел Шацких СберТех
Боремся с NPE вместе с Kotlin, Павел Шацких СберТехБоремся с NPE вместе с Kotlin, Павел Шацких СберТех
Боремся с NPE вместе с Kotlin, Павел Шацких СберТех
 
Implementing of classical synchronization problem by using semaphores
Implementing of classical synchronization problem by using semaphoresImplementing of classical synchronization problem by using semaphores
Implementing of classical synchronization problem by using semaphores
 
C++ Interview Question And Answer
C++ Interview Question And AnswerC++ Interview Question And Answer
C++ Interview Question And Answer
 
C++ questions And Answer
C++ questions And AnswerC++ questions And Answer
C++ questions And Answer
 
Linux Kernel, tested by the Linux-version of PVS-Studio
Linux Kernel, tested by the Linux-version of PVS-StudioLinux Kernel, tested by the Linux-version of PVS-Studio
Linux Kernel, tested by the Linux-version of PVS-Studio
 
Memory Manglement in Raku
Memory Manglement in RakuMemory Manglement in Raku
Memory Manglement in Raku
 
Hooking signals and dumping the callstack
Hooking signals and dumping the callstackHooking signals and dumping the callstack
Hooking signals and dumping the callstack
 
Namespaces
NamespacesNamespaces
Namespaces
 
Boost tour 1_44_0_all
Boost tour 1_44_0_allBoost tour 1_44_0_all
Boost tour 1_44_0_all
 
Effecient javascript
Effecient javascriptEffecient javascript
Effecient javascript
 
in c languageTo determine the maximum string length, we need to .pdf
in c languageTo determine the maximum string length, we need to .pdfin c languageTo determine the maximum string length, we need to .pdf
in c languageTo determine the maximum string length, we need to .pdf
 
Cocoa heads 09112017
Cocoa heads 09112017Cocoa heads 09112017
Cocoa heads 09112017
 
C++11 - A Change in Style - v2.0
C++11 - A Change in Style - v2.0C++11 - A Change in Style - v2.0
C++11 - A Change in Style - v2.0
 
Crafting Beautiful CLI Applications in Ruby
Crafting Beautiful CLI Applications in RubyCrafting Beautiful CLI Applications in Ruby
Crafting Beautiful CLI Applications in Ruby
 
1183 c-interview-questions-and-answers
1183 c-interview-questions-and-answers1183 c-interview-questions-and-answers
1183 c-interview-questions-and-answers
 
Compiler Design and Construction COSC 5353Project Instructions -
Compiler Design and Construction COSC 5353Project Instructions -Compiler Design and Construction COSC 5353Project Instructions -
Compiler Design and Construction COSC 5353Project Instructions -
 
Unit 4
Unit 4Unit 4
Unit 4
 
C programming language tutorial
C programming language tutorial C programming language tutorial
C programming language tutorial
 
李建忠、侯捷设计模式讲义
李建忠、侯捷设计模式讲义李建忠、侯捷设计模式讲义
李建忠、侯捷设计模式讲义
 
Writing a TSDB from scratch_ performance optimizations.pdf
Writing a TSDB from scratch_ performance optimizations.pdfWriting a TSDB from scratch_ performance optimizations.pdf
Writing a TSDB from scratch_ performance optimizations.pdf
 

Último

Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 

Último (20)

Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 

Abus at a glance