commit-gnue
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

gnue/docbook/Proposals/GComm chapters/codeinsig...


From: Jan Ischebeck
Subject: gnue/docbook/Proposals/GComm chapters/codeinsig...
Date: Mon, 10 Jun 2002 18:16:39 -0400

CVSROOT:        /cvsroot/gnue
Module name:    gnue
Changes by:     Jan Ischebeck <address@hidden>  02/06/10 18:16:39

Modified files:
        docbook/Proposals/GComm/chapters: codeinsight.sgml 
        docbook/Proposals/GComm: gcomm.sgml 

Log message:
        added more information about Internal structure

CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue/docbook/Proposals/GComm/chapters/codeinsight.sgml.diff?tr1=1.1&tr2=1.2&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue/docbook/Proposals/GComm/gcomm.sgml.diff?tr1=1.2&tr2=1.3&r1=text&r2=text

Patches:
Index: gnue/docbook/Proposals/GComm/chapters/codeinsight.sgml
diff -c gnue/docbook/Proposals/GComm/chapters/codeinsight.sgml:1.1 
gnue/docbook/Proposals/GComm/chapters/codeinsight.sgml:1.2
*** gnue/docbook/Proposals/GComm/chapters/codeinsight.sgml:1.1  Fri May 31 
22:04:04 2002
--- gnue/docbook/Proposals/GComm/chapters/codeinsight.sgml      Mon Jun 10 
18:16:39 2002
***************
*** 127,151 ****
      </title>
  
  
!     <para>
        (to be written)
! </para>
! <sect2><title>How a client works</title>
  <para>
! Client program needs to use services on Server X. As specified by the
! end-user in its configuration file, it will use the XML-RPC adapter.
  </para><para>
  The client program gets a GComm interface instance by calling
  GComm.attach(). A ClientAdapter is returned.
  
  </para>
- </sect2>
- <sect2><title>Simple Example</title>
- <para>
  
! Example IDL:</para>
! <programlisting>
!   Module DonutProvider {
  
      Module Management {
  
--- 127,200 ----
      </title>
  
  
! <!--    <para>
        (to be written)
! </para>-->
! <sect2>
! <title>How a client works - a simple example</title>
  <para>
! A client program needs to use services on Server X. As the Server provides
! its services per XML-RPC the client program will use XML-RPC too.
  </para><para>
  The client program gets a GComm interface instance by calling
  GComm.attach(). A ClientAdapter is returned.
  
  </para>
  
! <table frame="all">
!   <title>Services exported by server X</title>
!   <tgroup cols="2">
!     <thead>
!       <row>
!         <entry>GRPC file format</entry>
!         <entry>IDL file format</entry>
!       </row>
!     </thead>
!     <tbody>
!       <row>
!         <entry><programlisting>
! <![CDATA[
! <?xml version="1.0"?>
! <gnurpc>
! 
!   <service name="DonutPlace" binding="DonutPlace">
! 
!     <service name="Management">
! 
!       <method name="Restart"/>
! 
!       <method name="Shutdown">
!         <argument name="secondsToWait" type="integer" default="0"/>
!       </method>
! 
!       <method name="Status" return="string"/>
! 
!     </service>
! 
!     <service name="Bakery">
! 
!       <object name="BakingUnit">
!         <attribute name="flavor" type="string" readonly=""/>
!         <attribute name="unitLocation" type="string" readonly=""/>
!         <method name="requestDelivery" return="string">
!             <argument name="address" type="string"/>
!         </method>
! 
!       </object>
! 
!       <method name="getBakingUnit" 
!             return="&lt;DonutPlace.Bakery.BakingUnit&gt;">
!         <argument name="flavor" type="string"/>
!       </method>
! 
!     </service>
! 
!   </service>
! 
! </gnurpc>]]>
! </programlisting></entry>
!         <entry><programlisting>
!   Module DonutPlace {
  
      Module Management {
  
***************
*** 155,161 ****
  
      }
  
!     Module Factory {
  
        module BakingUnit {
  
--- 204,210 ----
  
      }
  
!     Module Bakery {
  
        module BakingUnit {
  
***************
*** 172,179 ****
  
    }
  
! </programlisting>
  
  </sect2>
  <sect2><title>Example Client</title>
  <programlisting>
--- 221,233 ----
  
    }
  
! </programlisting></entry>
!       </row>
!     </tbody>
!   </tgroup>
! </table>
  
+       
  </sect2>
  <sect2><title>Example Client</title>
  <programlisting>
***************
*** 183,189 ****
  
    server = GComm.attach('xmlrpc', params)
  
- 
    print "Donut Plant Operational Status: ",
    print server.DonutProvider.Management.Status()
  
--- 237,242 ----
***************
*** 221,230 ****
  </para>
  </sect2>
    </sect1>
!   <sect1>
!     <title>
!       Writing a RPC server with GComm
!     </title>
      <para>
        (to be written)
  </para>
--- 274,280 ----
  </para>
  </sect2>
    </sect1>
!   <sect1><title>Writing a RPC server with GComm</title>
      <para>
        (to be written)
  </para>
***************
*** 272,279 ****
      <title>
        Writing a new RPC communication driver with GComm
      </title>
      <para>
!       (to be written)
  </para>
    </sect1>
  </chapter>
--- 322,457 ----
      <title>
        Writing a new RPC communication driver with GComm
      </title>
+ <sect2>
+     <title>
+       Different ways to handle ansynchronous requests (rpc server side)
+     </title>
+ <blockquote>
+    <attribution>Python Library Reference, Release 2.1.3</attribution>
+    <para>There are only two ways to have a program on a single processor 
+ do ``more than one thing at a time.'' Multi-threaded programming is the 
+ simplest and most popular way to do it, but there is another very different
+  technique, that lets you have nearly all the advantages of multi-threading,
+  without actually using multiple threads. It's really only practical if your
+  program is largely I/O bound. If your program is CPU bound, then +
+  pre-emptive scheduled threads are probably what you really need. 
+  Network servers are rarely CPU-bound, however. </para>
+ </blockquote>            
+ <sect3>
+     <title>
+       Threading
+     </title>
      <para>
! For every request a thread is created. Every thread works on the same data.
! In comparison to the asyncore method, threads are claimed to be better for 
CPU bound operations, and not so good for I/o bound operations.
! (It is planned to do some benchmarking to evalute this issue.)
! 
! </para><para>
! Remark: In case of the <filename>pw_xmlrpc/ServerAdapter</filename> the 
ThreadingTCPServer is the standart. 
! <!--</para><para>
! You can find an implementation of it for the HTML protocol in 
! <filename>_helpers/ThreadingServer.py</filename>.-->
! </para></sect3>
! <sect3>
!     <title>
!       Forking
!     </title>
!     <para>
! (similar to threading, but instead of only creating a new thread, which still
! works on the same data, a fork creates a whole copy of the program. i.e. 
different forks  access different data.)
! </para>
! </sect3>
! <sect3>
!     <title>
!       Using the select()<footnote>
! <para>for select see: man 2 select (glibc function) or 
!  http://www.nightmare.com/medusa/programming.html (Medusa, a ??? server, is 
now in the core python lib)</para><para>
!  Beej's Guide to Network Programming has examples of usign select() in C too 
;)</para>
! </footnote> function to do all dispatching in one thread [module asyncore]
!     </title>
!     <para>
! This method is implemented in the python module 'asyncore'. It has some 
advantages over threads without the added complexity.
! 
! <!--</para><para>
! You can find an implementation of it for the HTML protocol in 
! <filename>_helpers/AsynCoreServer.py</filename>.
! </para>-->
! </sect3>
! <sect3>
!     <title>
!       One Example: a server for the IRC protocol
!     </title>
! <para> for IRC I think you need a dispatcher listening to IRC and starting up 
a new thread per method call (async)
! 
! </para><para>
! Problem:  irclib is synchronous and blocking
! </para>
! </sect3>
! </sect2>
! <sect2>
!     <title>
!       DirectoryServer.py
!     </title>
! <para><filename>_directory/DirectoryServer.py</filename> provides the class 
! DirectoryServer which builds an directory of all method calls out of
! the parsed GRPC object tree.
! </para><para> 
! A GRPC file is parsed by the Parser and builds an object tree without binding 
information, The directory server creates a dictonary indexed by method names 
containing binding, signature and helptext. The contents of this directory can 
be returned through introspection methods. In case of an incoming RPC request, 
the method call/dispatch is executed. This method will check for the correctnes 
and authenticity of the call by comparing it with the dictonary. If the call is 
correct, the binding information will be read out of the dictonary and the 
appropriate method will be called.
! </para>
! </sect2>
! <sect2>
!     <title>
!       Proxy Objects (Client Side)
!     </title>
! <para> what is the purpose of the Proxy object?
! </para><para> ProxyObjects are the glue to allow easy access on remote 
! function.
! After creating a ClientAdapter, there are two ways to call remote functions.
!  Only the second one depends on ProxyObjects.</para><para>
! A) by calling the method 'runMethod' of the ClientAdapter and passing the 
! the name of the remote function as a string.</para><para>
! B) by requesting a Service/Proxy Object, which you can access as if the 
! service would not be a distant but a local one.</para><para>
! In the case of calling an method 'getBakingUnit' from the service 
! 'Donutspace.Backery' method A/B would result in the following program code.
! </para><para>
! A) clientAdapter.runMethod('Donutspace.Backery.getBakingUnit',params,..)
! </para><para>
! B) Donutspace=clientAdapter.request('Donutspace')</para><para>
!    Donutspace.Backery.getBakingUnit(params,..)</para><para>
! 
! 
! 
! To understand how a Proxy object works, it is important to see what happens 
after a method is call like in B.</para><para>
! </para><para>  a) clientAdapter.request('Donutspace') creates an ProxyObject, 
which has an attribut 'attrpath' with the value 'Donutplace' and a link to the 
clientAdapter
! </para><para> b) the term 'Donutspace.Backery.getBakingUnit(params,..)' is
! executed. i.e. first the child 'Backery' of 'Donutplace' will be fetched by 
the method __getattr__. In case of 'Donutspace', which is a Proxy object the 
method __getattr__ is overwriten by ProxyObject.__getattr__(). The new function 
didn't check in the objects dictionary for such an attribut, but will create a 
new proxyObject instead. Now the 'attrpath' attribut of the new method is
! set to 'Donutplace.Backery'. The same happens at the end of the term, 
'getBakingUnit', which is a ProxyObject, that is callable.
! </para><para> c) at the moment you call 'Donutspace.sdfsdfsd()' the method 
__call__ of that Proxyobject is executed. This method calls 
adapter.runMethod(attrpath) i.e. adapter.runMethod('Donutspace.sdfsdfsd') 
! <!--</para><para>
! 
!  it builds up an object tree based on the request of an user. i.e. 
Donutspace.Backery.getStuff() will create a object 'Donutspace' object with a 
child 'Backery' with a child 'getstuff'. This last child is callable. i.e. 
after building this object tree the method 'Donutspace.Backery.getStuff' using 
ClientAdapter.runMethod
! </para><para> 'direct access' to 'string' mapping 
! </para><para> and the string is the whatever.whatever.whatever type thing?
! </para><para> so proxy object is really like it sounds it is a proxy or 
"reference" to an object?
! </para><para> like in the remote proxy design pattern
! </para><para> where does the method call get marshalled out?
! </para><para> er, that happens in the xmlrpc lib eh?
! </para><para> nevermind, I keep answering my own questions
! </para><para> it has two functions, a) Service to object mapping (started by 
the clientapp by parsing the Donutspace) b) stores information for dynamic 
objects. 
! </para><para> in case of b its a kind of remote proxy object
! </para><para> i.e. if you receive a dyn. object it returns a proxy Object 
with an attr like '[asdgadfgadfgdfhsdfg]'
! </para><para> so if you call a method of that object like myObj.doSomething 
the following steps happen.
! </para><para> 1. __getattr__('doSomething') creates a new proxyobject with 
the path '[asdgadfgadfgdfhsdfg].doSomething'
! </para><para>
! 
!  2. newproxyobj.__call__(params) execute adapter.runMethod(doSomething)
! </para><para>
! 
!  would somethgin like corba need a proxy object?
! </para><para>
!  btw. appserver will need some functions in GNUeRPC to indicate which method 
call belongs to which session. So if you have some function in IRC for that 
please remeber them, or directly add some methods  -->
  </para>
+ </sect2>
    </sect1>
  </chapter>
Index: gnue/docbook/Proposals/GComm/gcomm.sgml
diff -c gnue/docbook/Proposals/GComm/gcomm.sgml:1.2 
gnue/docbook/Proposals/GComm/gcomm.sgml:1.3
*** gnue/docbook/Proposals/GComm/gcomm.sgml:1.2 Fri May 31 22:04:04 2002
--- gnue/docbook/Proposals/GComm/gcomm.sgml     Mon Jun 10 18:16:39 2002
***************
*** 1,5 ****
! <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V3.1//EN" [
! <!-- $Id: gcomm.sgml,v 1.2 2002/06/01 02:04:04 siesel Exp $ -->
  <!ENTITY % global.chapters SYSTEM "chapters.ent">
  <!ENTITY % global.shared   SYSTEM "shared/shared.ent">
  
--- 1,5 ----
! <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [
! <!-- $Id: gcomm.sgml,v 1.3 2002/06/10 22:16:39 siesel Exp $ -->
  <!ENTITY % global.chapters SYSTEM "chapters.ent">
  <!ENTITY % global.shared   SYSTEM "shared/shared.ent">
  



reply via email to

[Prev in Thread] Current Thread [Next in Thread]