[GRASS-dev] [GRASS GIS] #2134: Create a general exit-safe interface to C libraries

GRASS GIS trac at osgeo.org
Sat Nov 23 11:24:36 PST 2013


#2134: Create a general exit-safe interface to C libraries
--------------------------------------------------+-------------------------
 Reporter:  wenzeslaus                            |       Owner:  grass-dev@…              
     Type:  enhancement                           |      Status:  new                      
 Priority:  normal                                |   Milestone:  7.0.0                    
Component:  Python ctypes                         |     Version:  svn-trunk                
 Keywords:  G_fatal_error, exit, multiprocessing  |    Platform:  All                      
      Cpu:  Unspecified                           |  
--------------------------------------------------+-------------------------

Comment(by huhabla):

 I have attached a new RPC server that is able to instantiate a persistent
 PyGRASS object in a remote process that can be accessed using an RPC
 interface, have a look at the attached file
 [[attachment:pygrass_rpc_interface.py]].

 To get it work i needed to patch the PyGRASS raster info object to avoid
 C-pointer that can not be pickled, see [[attachment:pygrass_raster.diff]].
 IMHO PyGRASS should avoid pointer and should use ctypes.byref() to pass
 pointers to GRASS C-functions. I think (i am not sure about this) that
 avoiding ctypes.pointer() may reduce memory leaks as well if objects like
 Cell_head() of Range() are managed by the Python garbage collector?

 Here an example how to use the PyGRASS RPC interface, reading some raster
 map info's and all rows:

 {{{
 #!python
 if __name__ == '__main__':
     import grass.script as grassscript
     import grass.pygrass.raster as pygrass

     grassscript.use_temp_region()
     grassscript.run_command("g.region", n=80.0, s=0.0, e=120.0, w=0.0,
                       t=1.0, b=0.0, res=10.0, res3=10.0)
     grassscript.run_command("r.mapcalc", expression="test = row()",
                             overwrite=True, quiet=True)

     # Start the server and create a RasterRow remote object
     # that is initialized with the raster map name
     kargs = {"name":"test"}
     server = RPCServer(pygrass.RasterRow, kargs)

     # Get some raster map info
     info = server.get_property("info")
     print "Rows:", info.rows
     print "Cols:", info.cols
     print "N:", info.north
     print "S:", info.south
     print "E:", info.east
     print "W:", info.west

     # Open the raster map for row access
     kargs = {}
     server.call("open", kargs)

     # Read all rows
     for row in xrange(info.rows):
         kargs = {"row":row}
         ret = server.call("get_row", kargs)
         print "Row:", row, ret

     # Close the raster map
     kargs = {}
     server.call("close", kargs)

     grassscript.del_temp_region()
 }}}

 Result:

 {{{
 GRASS 7.0.svn (nc_spm_08):~/src > python pygrass_rpc_interface.py
 Rows: 8
 Cols: 12
 N: 80.0
 S: 0.0
 E: 120.0
 W: 0.0
 Row: 0 [1 1 1 1 1 1 1 1 1 1 1 1]
 Row: 1 [2 2 2 2 2 2 2 2 2 2 2 2]
 Row: 2 [3 3 3 3 3 3 3 3 3 3 3 3]
 Row: 3 [4 4 4 4 4 4 4 4 4 4 4 4]
 Row: 4 [5 5 5 5 5 5 5 5 5 5 5 5]
 Row: 5 [6 6 6 6 6 6 6 6 6 6 6 6]
 Row: 6 [7 7 7 7 7 7 7 7 7 7 7 7]
 Row: 7 [8 8 8 8 8 8 8 8 8 8 8 8]
 }}}

 IMHO the RPC interface design should provide a blueprint how to implement
 a remote digitizer using PyGRASS to access vector or raster maps. I hope
 that most of the PyGRASS functionality will be accessible using this
 approach.

 Note: with this approach you will create a subprocess for each raster or
 vector map that should be modified. Each subprocess will manage only one
 object. The subprocess can manage several objects by using a session id.
 But IMHO this is not a good idea. In case one object calls G_fatal_error()
 or segfaults, all other objects will be killed as well.

 PyGRASS may need more patching to make the objects that will be exchanged
 between client and server picklable (see PyGRASS raster info object patch
 [[attachment:pygrass_raster.diff]]).

 This RPC interface will not replace the new PyGRASS messenger interface
 nor the tgis specific raster info access RPC implementation. Calling
 simple C-functions for each map in a space time raster datasets (STRDS)
 using an RPC interface is much faster than creating a subprocess and a
 raster object for each map in a STRDS.

 Hence, there are different solutions for different needs. :)

-- 
Ticket URL: <http://trac.osgeo.org/grass/ticket/2134#comment:15>
GRASS GIS <http://grass.osgeo.org>



More information about the grass-dev mailing list