the 'Freiburg' project is an replacement for shared libraries on Unix, Windows and Mac OS X ... [the 'Freiburg project FAQ] ---- '''goals''' ---- * convert a shared library into an ''module'' * every ''module'' uses its ''own'' object-space (e.g., it is an execuatble) * an application is a collection of ''modules'' * the ''modules'' communicate with a ''data-bus'' * the ''data-bus'' is implemented as a shared/static library * the ''module'' can reside local or remote * if ''remote'' the ''module'' is started by the ''inetd'' server and using tcp sockets * if ''local'' the module is started by the application starter and using uds sockets * the ''module'' can be created with any programming language as long the the language is able to link again the ''data-bus'' * the ''module'' is independent of the application interface (e.g., no dynamic linking) * once a ''module'' was created it can be used with any programming language ---- '''usability study 1''' ---- I maintain an application based on REMEDY-Ars running a workflow application. The application is running on a SUN server using a local SYBASE database. To monitor the server I wrote an ARS ''module'' to check the health status of ARS and the workflow application. The ''module'' was developed on SUN Solaris using a gcc compiler and a non free REMEDY-Ars api. To monitor the server I'm using ''moods'' as front-end and the ''module'' as data provider. The ''moods'' application is using a graphic and a text based output devices. The quality of information provided combined with the easiness of using ''moods'' created a ''killer'' application with a strong request for additional installations. To minimize the installation requirements and maximize the support quality I decided to run the ''module'' on a ULTRA SPARC 10 and only ship a generic ''moods'' application for different kind of UNIX and WINDOWS environments. With using the ''module'' technology I do not need to port the data provider to different environments and was able to support environments with no api support by the REMEDY-Ars supplier. [RHS] It sounds like an implementation of a ''Service Oriented Architecture''. While each ''module'' can provide functionality, they're not libraries per se, so much as ''services'' that other modules or programs can then use. ---- '''the 'Freiburg' project and the 'command line'''' ---- the traditional ''unix'' command line was developed to create complex filters based on simple tools: tool1 | tool2 | tool3 1. how it works -> a tool is nothing more than a ''module'' with specific capabilities to manipulate an input stream. The collection of tools combined with ''pipes'' is an application. The communication between the tools based on '''strings''' with no additional format information. The problem is to implement for ''every'' tool a parser to split the input stream into useable data blocks. 2. evolution step one -> instead using a '''string''' based data stream you can use a '''structured string''' based data stream (e.g. ''xml'' is an example). This make it easy to parse the data stream and add additional capability to handle complex data types (e.g. float, integer ...) 3. evolution step two -> instead of using one direction communication you can use sockets to allow ''answers'' send back to the parent |-tool2 tool1-| |-tool3-|-tool4 |-tool5 more information will be available ''[escargo] 21 Aug 2004'' - Couldn't the distinction between step one and step two also be described as using ''objects with string-based serializations'' being sent between your ''modules''? As long as all communicating modules agree on the mechanisms for encoding and decoding, it does not matter if your serialization mechanism is [XML], [YAML], or anything else. (In fact, if it's properly layered, you could even be going through an ssh tunnel.) -> YES ---- '''the 'Freiburg' project and 'Tcl'''' ---- this is an example-link between 'Freiburg' and 'Tcl' package require TestOnFreiburg set FH [TestOnFreiburg::Start -name TclTestOnFreiburg -tcp -inetd -host myserver -port myapp] set RET [TestOnFreiburg::Echo2 $FH -int2 12345] puts "Answer: $RET" rename $FH "" description: start ''test'' based on 'Freiburg' using the ''module'' on server ''myserver'' using port ''myport'' and call procedure ''Echo2'' with a 2-byte integer 12345 as argument the communication between ''application'' and ''module'' is based on different data-types INT2 .... 2 byte integer INT4 .... 4 byte integer INT8 .... 8 byte integer FLT4 .... 4 byte float FLT8 .... 8 byte float PTR ..... pointer STR ..... \0 terminated string BIN ..... binary LST ..... list can contain all types [RHS] Given the ''rename $FH ""'', it seems like ''$FH'' is a command. If so, why not make it so that you can call it directly to get results, ie: set RET [$FH Echo2 -int2 12345] because it is just an wrapper for: proc TestOnFreiburg::Echo2 { Ctx args } { return [$Ctx send -wait -type ECO2 $args] } description: * -wait, open an transaction (e.g. expect result) * -type, used typed arguments (if no -type tcl will choose the right data-type) * ECO2, use function defined by token ''ECO2'' ---- '''the 'Freiburg' project and 'C'''' ---- The 'Freiburg' project was written in 'C' an 'C' is the native interface: int main(int argc, char **argv) { ContextS *context; // the initial context BufferLS *largv = BufferLCreateArgv(NULL, --argc, ++argv); MsgqueS *a_msgque; INT2 ret; // create the ContextS ErrorCheck(ContextCreate(largv, &context)); // call Echo2 struct SendS * const send = context->msgque->send; SendSTART(send); SendTOKEN(send, "ECO2", NULL, NULL /* transaction not needed */); Send2(send, 12345); ErrorCheck(SendEND(send)); // do some work .... // read the result ErrorCheck(ReadHDR(context->msgque->read, &a_msgque)); ErrorCheck(Read2(a_msgque->read, &ret)); printf("Answer:%i\n", ret); error: ErrorSSend(CONTEXT_SAVE_ERROR(context), __func__); ContextDelete(&context); exit(EXIT_SUCCESS); return 0; } ---- [Lars H]: One great obstacle this kind of project faces is how to make different modules ''communicate'' rather than just send data to each other, i.e., how does one module do to understand the data another module is sending to it? One could declare that the project only bothers with getting the binary data across ungarbled and leave it at that, but that just leaves a huge amount of work for the writer of a module to take care of. Unix pipes wouldn't have been of much use had not most of the tools in the pipe at least had the text file format in common. It is likely that Freiburg will similarly need a common basic format. From list of data-types above, it seems to me that the developers might find it interesting to compare their work with that which has been done on the '''Multi''' Protocol (MP). The official home for that is http://www.symbolicnet.org/areas/protocols/mp.html but unfortunately many of the links on that page to papers are now broken. I have however been able to find some copies via CiteSeer; [http://citeseer.ist.psu.edu/context/195250/4940] has links to many of the relevant papers. An interesting feature of MP is the way that one can mix data with an explicit type specification for each datum with long blocks of data that do not have individual type specifications, to reduce communication overhead. Communication formats is very much a Catch 22. If it is too hard to encode and decode messages, then programmers will not bother. If messages are not properly encoded, then they cannot be interchanged. ---- '''FAQ''' ---- ''1. how to make different modules communicate'' both sites using the same communication library ''libfreiburg'' which implement the ''protocoll''. Application software only using the ''freiburg'' API (e.g. SendI2). ''2. what exactly does 'libfreiburg''' 1. setup the communication (local or remote) and connect to the server 2. choose the right byte-order (little/big endian) 3. verify 'module' api version 4. if error happen, propagate the error(s) to the client 5. do all the ''send'' and ''recv'' stuff 6. do (if necessary) the casting of different types 7. after the work was done do a 'clean' shutdown of the communication ''3. how does one module do to understand the data another module is sending to it?'' 1. 'understand' means knowing the exact definition of the procedures called 2. the programmer (e.g server and client) using the same ''interface'' 3. the ''interface'' is the name of the service provided (e.g. ECO2), the arguments expected (e.g. INT2) and the return value (e.g. INT2) 4. the 'interface' version is the 'module' api version ''4. It is likely that 'Freiburg' will similarly need a common basic format?'' the common format is: [PACKAGE]=[HEADER]+[BODY] [HEADER]=HDR+BinaryFlag|StatisticFlag|DebuggingFlag|VerboseFlag+ MyContext+RemoteContext+BodySize+Token+TokenPtr+TransactionPtr [BODY]=[BODYItem]+[BODYItem]+ ... [BODYItem]=ItemSize+ItemType+ItemValue reading and writing the format is done by the ''libfreiburg'' library ''5. What does 'Freiburg' not do?'' 1. no login verfication 2. no encoding or decoding of binary data 3. no encryption or decryption of binary data 4. no transparent service-detection ''6. What is the overhad of 'Freiburg''' 1. Win32 dll striped currently has 76288 bytes 2. Linux on Athlon with 1040MHz using Unix Domain Sockets has a transaction overhad of 20 usec (this is the time for a round-trip: calling remote procedure; remote echo of the argument and wait on result)