[Glass] GsDevKit Server Blocks for Thin Client appications ... pre-announcement

Dale Henrichs via Glass glass at lists.gemtalksystems.com
Thu May 28 15:38:19 PDT 2015


Pierre,

Again, very cool ... I am nearing the end of my (intense) work on 
GemStone 3.3 so we should touch bases when I am done.

Dale

On 5/25/15 1:47 PM, Pierre CHANSON wrote:
> Hi all, finally I found some time to work on this.
>
> first, based on the PointerDetective of Ben 
> (http://smalltalkhub.com/#!/~BenComan/PointerDetective 
> <http://smalltalkhub.com/#%21/%7EBenComan/PointerDetective>) I did a 
> RPointerDetective using Roassal and usable on a Pharo image.
>
> Then I made a second class adapted to work on tODE, given a TDShell 
> and using server blocks.
>
> Here is a little video of the result: https://vimeo.com/128790347
>
>
> The prerequisite are the last version of Roassal and the package: 
> http://smalltalkhub.com/#!/~PierreChanson/RPointerDetective 
> <http://smalltalkhub.com/#%21/%7EPierreChanson/RPointerDetective>
>
> The first part is on a Pharo image (could be a tODE image too) with 
> the script:
>
> --------------------------------------------
> ob := 'OBJ'.
> ar := { ob. 12 }.
> e := (RTBox new) elementOn: ar.
> v := RTView new.
> v add: e.
>
> RPointerDetective on: ob
> -------------------------------------------------
>
> Second part is on tODE, given an oop of server object.
>
> The first script :
>
> RPointerDetective onServerFindAllReferencePathsToObject: 154679809 
> shell: shell
>
> And the second:
>
> RPointerDetective onServer: 154679809 shell: shell
>
> The first script is using the 
> findAllReferencePathsToObjects:limitObjArray:printToLog:. In that case 
> the graph is directly given by the gemstone method and displayed on 
> the view on clic.
>
> The second script is using the gemstone method findAllReferences. here 
> tODE is calling the method when the object is clicked on the view. 
> This one can be dangerous because we do not take care of the number of 
> object that are going to be displayed...
>
> There is still a lot of interesting things to do, with interactions on 
> the view for example with the possibility to dinamically change the 
> colors given a block or display the pointersFrom of a node or the 
> possibility to open a tODE inspector etc.
>
> cheers,
>
> Pierre
>
> 2015-04-30 20:14 GMT-03:00 Pierre CHANSON <chans.pierre at gmail.com 
> <mailto:chans.pierre at gmail.com>>:
>
>     Oh thanks ! I like this method now,  I am going to give a try :)
>
>     2015-04-30 14:59 GMT-03:00 Dale Henrichs via Glass
>     <glass at lists.gemtalksystems.com
>     <mailto:glass at lists.gemtalksystems.com>>:
>
>         +1 :)
>
>
>         On 04/30/2015 10:26 AM, Mariano Martinez Peck via Glass wrote:
>>         Hi Pierre,
>>
>>         Do you want to do a super killer example of using Roassal and
>>         ServerBlocks?
>>
>>         As you may known, since in Smalltalk you cannot delete an
>>         object (compared to relational DBs where you do delete rows),
>>         removing all references to an object so that is GCed,
>>          sometimes is not a walk in park. Ben was tired of using the
>>         Pharo Explorer for that, and he did this:
>>         http://smalltalkhub.com/#!/~BenComan/PointerDetective
>>         <http://smalltalkhub.com/#%21/%7EBenComan/PointerDetective>
>>
>>         If that is valuable in Pharo, imagine in GemStone. And now,
>>         with the serverBlocks, that would be very easy.
>>
>>         Just see today's email of Otto saying he couldn't GC an object.
>>
>>         To find pointers to an object in GemStone:
>>
>>         SystemRepository findReferencePathToObject: 123456789 asObject
>>
>>
>>         yeah...maybe I should try it myself :)
>>
>>
>>
>>
>>
>>         On Wed, Apr 29, 2015 at 7:42 PM, Pierre CHANSON
>>         <chans.pierre at gmail.com <mailto:chans.pierre at gmail.com>> wrote:
>>
>>             Thanks again Dale !
>>
>>             here are three small examples using these blocks in the
>>             roassal workspace of tODE: https://vimeo.com/126435220
>>
>>             I highlight here the server blocks in red.
>>
>>             The first one is a Mondrian view of the class Collection
>>             (server side) with all it's subclasses.
>>             The classes are processed in the block and stocked
>>             statically on the variable "classes".
>>
>>             --------------------------------------------------------------------------------------------------------------------------------------
>>             | b classes |
>>             classes :=shell onServerDo:[Collection withAllSubclasses
>>             collect: [ :c | c name -> {(c superClass name). ((c
>>             instVarNamed: #methDicts asString) numElements)}]].
>>
>>             b := RTMondrian new.
>>             b shape circle.
>>             b nodes: classes.
>>             b edges connectFrom: [:e | classes detect: [ :c | c name
>>             = e value first ] ifNone:[ nil ]] .
>>
>>             b shape bezierLineFollowing: [:e | classes detect: [ :c |
>>             c name = e value first ] ifNone:[ nil ]];
>>                  color: (Color blue alpha: 0.2).
>>
>>
>>             b normalizer
>>                 normalizeSize: [:e | e value second ] using: #sqrt;
>>                 normalizeColor: [:e | e value second ] using: (Array
>>             with: Color green with: Color red) using: #sqrt.
>>             b layout cluster.
>>             b build.
>>             b view open
>>             --------------------------------------------------------------------------------------------------------------------------------------
>>
>>             The second script use the RTExploraBuilder to do the same
>>             process, but this time the builder call dynamically the
>>             server on clics (we are using the oop of objects).
>>
>>             --------------------------------------------------------------------------------------------------------------------------------------
>>             | builder |
>>                 builder := RTExploraBuilder new.
>>                 builder shape circle
>>                     size: 30;
>>                     color: (Color blue alpha: 0.5);
>>                     if: [ :cls |
>>                         (shell onServerDo: [ (Object _objectForOop:
>>             (cls value)) subclasses size]) = 0 ] fillColor: (Color
>>             red alpha: 0.5).
>>                 builder
>>                     layout: [RTClusterLayout new horizontalGap: 80];
>>                     onClickExplore: [ :cls |
>>             shell onServerDo: [ ((Object _objectForOop: (cls value))
>>             subclasses collect: [:c | c asString -> c asOop]) asArray ]
>>                         ];
>>                     withPopup: [:cls | cls key];
>>                     dragChildren;
>>                     node: (shell onServerDo: [Collection asString ->
>>             Collection asOop]);
>>                     open.
>>             --------------------------------------------------------------------------------------------------------------------------------------
>>
>>
>>             The last script is about users. This need the last
>>             version of Roassal. We present some selection menus, a
>>             button and a radar Chart. Created with the RTMenuBuilder
>>             the button add a new user on the server with the
>>             characteristics selected in the other menus and present
>>             the characteristics of the added users on a Kiviat chart
>>             on the view.
>>
>>             --------------------------------------------------------------------------------------------------------------------------------------
>>             |nameMenus privilegeMenus groupMenus|
>>                 v := RTView new.
>>
>>                 kiv := RTKiviatBuilder new view: v.
>>                 n := RTMultiLinearColorForIdentity new objects: (kiv
>>             objects).
>>                 kiv shape circle color: [ :value | n rtValue: value
>>             kiviatNode named]; size: 10.
>>
>>
>>                 kiv addMetric: [ :v | v second size] max: 5 title:
>>             'groups'.
>>                 kiv addMetric: [ :v | v third size] max: 5 title:
>>             'privileges'.
>>                 kiv addMetric: [ :v | v first size] max: 10 title:
>>             'name'.
>>
>>
>>                 kiv activatePolygons.
>>                 kiv build.
>>
>>                 b := RTMenuBuilder new view: v.
>>
>>                 nameMenus := Array with: ('Henri'->[:m |]) with:
>>             ('Bob'->[:m |]) with: ('Robert'->[:m |]).
>>                 groupMenus := Array with: ('Subscribers'->[:m |])
>>             with:('Publishers'->[:m |]).
>>                 privilegeMenus := Array with:
>>             ('ObsoleteStatistics'->[:m |]) with:('UserPassword'->[:m
>>             |]) with:('SessionAccess'->[:m |]).
>>
>>
>>                 b menu: 'add User' callback: [
>>                     |name groups privileges |
>>
>>                     name := (nameMenus detect: [ :m | m selected ]) name.
>>                     groups := (groupMenus select: [:m | m selected])
>>             collect: [:g | g name].
>>                     privileges := (privilegeMenus select: [:m | m
>>             selected])  collect: [:p | p name].
>>             shell onServerDo: [
>>                         AllUsers addNewUserWithId: name password: ''
>>             defaultObjectSecurityPolicy: nil privileges: privileges
>>             inGroups: groups .
>>                         System commitTransaction.].
>>                     kiv addDynamicObject: (Array with: (name) with:
>>             (groups) with: (privileges))
>>             ].
>>
>>                 nameMenus := b menu: 'user' subcheckmenus: nameMenus
>>             background: (Color red alpha: 0.3).
>>                 RTMenuGroup on: nameMenus.
>>                 nameMenus first selected: true.
>>
>>
>>                 groupMenus := b menu: 'groups' subcheckmenus:
>>             groupMenus background: (Color blue alpha: 0.3).
>>                 groupMenus first selected: true.
>>
>>
>>                 privilegeMenus := b menu: 'privileges' subcheckmenus:
>>             privilegeMenus background: (Color green alpha: 0.3).
>>
>>                 privilegeMenus first selected: true.
>>
>>                 b view open.
>>             --------------------------------------------------------------------------------------------------------------------------------------
>>
>>              Pierre
>>
>>
>>
>>
>>             2015-04-23 19:58 GMT+02:00 Mariano Martinez Peck via
>>             Glass <glass at lists.gemtalksystems.com
>>             <mailto:glass at lists.gemtalksystems.com>>:
>>
>>
>>
>>                 On Wed, Apr 22, 2015 at 1:53 AM, Richard Sargent
>>                 <richard.sargent at gemtalksystems.com
>>                 <mailto:richard.sargent at gemtalksystems.com>> wrote:
>>
>>                     Mariano,
>>
>>                     Depending on what you mean by "execute stuff on
>>                     server Y", 3.2 includes something called
>>                     GsExternalSession. It it capable of executing
>>                     Smalltalk specified in Block on a separate
>>                     session against the same stone or a different one.
>>
>>                     It doesn't support copying object graphs, but if
>>                     your definition of execute stuff has limited
>>                     requirements for exchanging data, it could be
>>                     what you are looking for.
>>                     See the 3.2 documentation for details.
>>
>>
>>                 Good to know too. Thanks Richard.
>>
>>                     On Apr 21, 2015 7:01 PM, "Mariano Martinez Peck
>>                     via Glass" <glass at lists.gemtalksystems.com
>>                     <mailto:glass at lists.gemtalksystems.com>> wrote:
>>
>>
>>
>>                         On Thu, Apr 16, 2015 at 2:23 AM, Dale
>>                         Henrichs via Glass
>>                         <glass at lists.gemtalksystems.com
>>                         <mailto:glass at lists.gemtalksystems.com>> wrote:
>>
>>                             A GsDevKit Server Block[1] is a block
>>                             that is written in-line in client
>>                             Smalltalk, but is executed in GemStone.
>>                             For example the following expression is
>>                             executed in a standard Pharo workspace:
>>
>>                               | shell x y |
>>                               shell := TDShell forSessionNamed: 'devKit'.
>>                               x := 3.
>>                               y := 4.
>>                               shell onServerDo: [ x + y ].
>>
>>
>>
>>                         Dale,
>>
>>                         I know (because I already asked a few
>>                         months/years ago) that from a stone X you can
>>                         do a remote login on stone Y and execute
>>                         stuff in Y. But now I wonder....could server
>>                         blocks also work for gemstone-gemstone? (my
>>                         gut feelings tell me that yes) I mean, could
>>                         I run the above code from GemStone itself?  
>>                         That would automatically resolve all the
>>                         remote login stuff and the ston serialization.
>>                         Thanks in advance,
>>
>>
>>
>>                             and the `[3 + 4 ]` block is executed in
>>                             GemStone using the `devKit` session
>>                             description to log into the stone. The
>>                             temp vars x and y referenced in the
>>                             server block and defined in Pharo are
>>                             shipped across the wire to GemStone along
>>                             with block source where the block source
>>                             is compiled and executed. The result is
>>                             then shipped back across the wire and
>>                             returned as the result of #onServerDo:
>>                             message in Pharo. Pharo execution can
>>                             continue on using the result. STON[2] is
>>                             used to serialize the objects that are
>>                             shipped across the wire.
>>
>>                             For any of you familiar with
>>                             underpinnings of GemTools, Jade or tODE,
>>                             this is not necessarily ground-breaking
>>                             technology, however, exposing this
>>                             capability to developers just may be.
>>
>>                             It has been a long standing crime that
>>                             developers in the Pharo community choose
>>                             to use MongoDB and MySQL over GemStone,
>>                             but frankly the problem is that (until
>>                             now) we have not had a simple
>>                             client-based solution for adding
>>                             GemStone-based persistence for native
>>                             Pharo applications - the pharo developers
>>                             have not really had a choice.
>>
>>                             Being able to embed server blocks in
>>                             client code certainly qualifies as
>>                             simple. Solution(?), well that remains to
>>                             be seen, but I am optimistic.
>>
>>                             As a more concrete example, here's Pharo
>>                             workspace code that uses NeoCSV running
>>                             in Pharo to load stone objects in a
>>                             Dictionary in GemStone:
>>
>>                             'NeoCSVBenchmark.csv' asFileReference
>>                             readStreamDo: [ :stream |
>>                               | reader converter buffer bufCnt
>>                             numRecords records |
>>                               converter := [ :string |
>>                             NeoNumberParser parse: string ].
>>                               reader := NeoCSVReader on:
>>                             (ZnBufferedReadStream on: stream).
>>                               reader
>>                             recordClass: NeoCSVTestObject;
>>                             addIntegerField: #'x:';
>>                             addIntegerField: #'y:';
>>                             addIntegerField: #'z:'.
>>                               buffer := Array new: 1000.
>>                               bufCnt := 0.
>>                               [ reader atEnd ]
>>                             whileFalse: [
>>                                   bufCnt := bufCnt + 1.
>>                                   buffer at: bufCnt put: reader next.
>>                                   bufCnt = buffer size
>>                             ifTrue: [
>>                             numRecords := bufCnt.
>>                             records := buffer.
>>                             DevKitShell
>>                             onServerDo: [
>>                             1 to: numRecords do: [ :index |
>>                             | record |
>>                             record := records at: index.
>>                             NeoCSVDictionary at: record x put: record ].
>>                             System commitTransaction.
>>                             nil ].
>>                             bufCnt := 0 ] ] ].
>>                                DevKitShell onServerDo: [ System
>>                             commitTransaction ]
>>
>>                             The code ships 1000 instances of
>>                             NeoCSVTestObject at a pop to GemStone.
>>                             Using the above technique, one can easily
>>                             arrange to store some pretty large object
>>                             graphs in GemStone ... Efficient queries
>>                             based on standard Smalltalk can be
>>                             written on the client and transparently
>>                             performed in GemStone (see the
>>                             GsDevKitServerBlocks doc[1] for the
>>                             complete example).
>>
>>                             Server blocks do not duplicate the
>>                             functionality GemBuilder for
>>                             Smalltalk[6][7] which provides
>>                             transparent replication and maintenance
>>                             of objects between the client and server.
>>                             With server blocks you end up with
>>                             disconnected copies of server objects.
>>
>>                             Because of this disconnect, I think the
>>                             best way to architect an application
>>                             using server blocks, is to plan on
>>                             "executing all business logic" on the
>>                             server --- If you are using an MVC
>>                             pattern, the M would primarily be managed
>>                             on the server while the VC would be
>>                             managed on the client.
>>
>>                             As an application evolves, the code can
>>                             migrate back and forth between client and
>>                             server as needed.
>>
>>                             Most of the server blocks code leverages
>>                             tODE and has been in use for several
>>                             years. The code that spelunks in the
>>                             block structure and extracts the _value_
>>                             of temp variables is only a couple of
>>                             days old and has some pretty rough edges
>>                             (notice the odd placement of temp
>>                             variables and declarations in the above
>>                             example).
>>
>>                             The server-side debugger and inspectors,
>>                             etc. will use tODE (at least for now) ...
>>                             in the server blocks doc[1] I demonstrate
>>                             an #exportClassToServer: to illustrate
>>                             the potential to share code in weird and
>>                             wonderful ways between the client and server.
>>
>>                             If you have the interest/opportunity to
>>                             take this code for a spin, let me know. I
>>                             have written instructions[5] for
>>                             installing the experimental Roassal
>>                             Visualization code[4] (GemStone and
>>                             Pharo3.0 or Pharo4.0) for Pierre Chanson
>>                             and those instructions can be used for
>>                             doing work with GsDevKit
>>                             Server Blocks. There are a handful of
>>                             obvious things that need to be done:
>>                               - connection pools
>>                               - coordinated client/server debuggers
>>                               - client-side exception handlers for
>>                             server errors
>>                               - more???
>>                             and if folks express interest in start to
>>                             do exploratory work with server blocks,
>>                             then I will make time to provide support.
>>
>>                             I am hoping to have something to announce
>>                             by Smalltalks in November,so it would be
>>                             useful if some experienced GemStoners
>>                             tried things out before then...
>>
>>                             I do have to finish up the documentation
>>                             for GsDevKitHome 1.0.0 and tODE 0.1.0 and
>>                             I'm also committed to doing some work on
>>                             the 3.3 GemStone release, so we'll see
>>                             how that goes:)
>>
>>                             I also think that server blocks can be
>>                             very useful for the "develop in Pharo,
>>                             deploy in GemSstone" crowd, since it will
>>                             be possible to write "pharo-based
>>                             scripts" to perform server-side tasks ...
>>
>>                             Questions or comments?
>>
>>                             Dale
>>
>>                             [1]
>>                             https://github.com/GsDevKit/gsDevKitHome/blob/dev/docs/articles/gsDevKitServerBlocks.md#gsdevkit-server-blocks
>>                             [2]
>>                             https://github.com/GsDevKit/ston#ston---smalltalk-object-notation
>>                             [3] https://vimeo.com/123261640
>>                             [4]
>>                             https://github.com/GsDevKit/gsDevKitHome/tree/dev/projects/roassal#roassal-visualization
>>                             [5]
>>                             https://github.com/GsDevKit/gsDevKitHome/blob/dev/projects/roassal/devBootstrap.md
>>                             [6]
>>                             http://gemtalksystems.com/products/gbs-vw/
>>                             [7]
>>                             http://gemtalksystems.com/products/gbs-va/
>>
>>                             _______________________________________________
>>                             Glass mailing list
>>                             Glass at lists.gemtalksystems.com
>>                             <mailto:Glass at lists.gemtalksystems.com>
>>                             http://lists.gemtalksystems.com/mailman/listinfo/glass
>>
>>
>>
>>
>>                         -- 
>>                         Mariano
>>                         http://marianopeck.wordpress.com
>>
>>                         _______________________________________________
>>                         Glass mailing list
>>                         Glass at lists.gemtalksystems.com
>>                         <mailto:Glass at lists.gemtalksystems.com>
>>                         http://lists.gemtalksystems.com/mailman/listinfo/glass
>>
>>
>>
>>
>>                 -- 
>>                 Mariano
>>                 http://marianopeck.wordpress.com
>>
>>                 _______________________________________________
>>                 Glass mailing list
>>                 Glass at lists.gemtalksystems.com
>>                 <mailto:Glass at lists.gemtalksystems.com>
>>                 http://lists.gemtalksystems.com/mailman/listinfo/glass
>>
>>
>>
>>
>>
>>         -- 
>>         Mariano
>>         http://marianopeck.wordpress.com
>>
>>
>>         _______________________________________________
>>         Glass mailing list
>>         Glass at lists.gemtalksystems.com  <mailto:Glass at lists.gemtalksystems.com>
>>         http://lists.gemtalksystems.com/mailman/listinfo/glass
>
>
>         _______________________________________________
>         Glass mailing list
>         Glass at lists.gemtalksystems.com
>         <mailto:Glass at lists.gemtalksystems.com>
>         http://lists.gemtalksystems.com/mailman/listinfo/glass
>
>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.gemtalksystems.com/mailman/private/glass/attachments/20150528/24a70f98/attachment-0001.html>


More information about the Glass mailing list