Saturday, August 27, 2016

GLIB/GTK+3 Network Programming using UDP on the Raspberry Pi





My plan was to create a CommandLine and GTK based Display service for use with my Raspberry Pi projects.  I already have a GitHub package that includes a node Registry for locating existing Pis on the network.  This registry also contains a list of network based services, like the display service I’m planning to write.

The usage model assumes you’ve written some program that collects data from the many different sensors available to the Raspberry Pi, like temperature sensors, ultrasonic distance sensors. Etc.   When writing these sensor programs, displaying the output would be helpful, but continuously writing the display routines is distracting.  This is where the display service programs come into play; it makes displaying sensor results easier to implement and defines a network model that allows you to build other network services using the existing registry.

I choose UDP as the transport protocol to acknowledge the unreliable behaviors present in Internet of Things (IOT) devices and platforms.  For me this means, that one of my Pis (which is providing a service) may not be working or online and I don’t want its absence to hang up my primary program.  UDP allows us to send requests which we hope will be serviced, but it won’t be the end of the world if there not!

I have a fair amount of GTK+2 and GLIB programming experience and thought using the newer versions of both would be an interesting exercise, and also shorten the development time.  Version GTK+3 and GLIB+2 was my choice.  Turns out that if I were not using UDP that assertion would have been true.  Glib does support UDP with several workable and helpful improvements.  However, the actual methods were difficult to identify and several trials failed because of the mechanics of UDP versus TCP.  I tried and wanted to use the high-level networking APIs GLIB provides like GSocketClient, GSocketService, GThreadedSocketService, and GIOChannels only to discover that they are TCP specific and don’t support UDP; at lest in the fashion I was planning to use them.  The primary tell was the inclusion of a ‘Listen’ or ‘Listener’ API.  

TCP, being session based, includes the listener as a regular feature of the session building process; GLIB’s high-level networking APIs automate the invocation of the listener and sometimes bind operation as part of their high-level notion.  The listener api is not needed for UDP since we never create a session between the communication partners.  Invoking a listener on a UDP socket immediately produces an error.  No worries though, the GSocket API fully supports both TCP and UDP communications.  Using a handful of the GSocket grouped APIs.  I was able to create a polished command line version of this display service in less than 150 lines of C code.

GLIB includes many advanced and simplified programming facilities, and is also the underlying support for the graphics library GTK+.  To provide a graphical UI for my display service, I will use GTK/GLIB to implement it.  One key feature of GLIB that was interesting to me was its Event Loop.  A facility that allows all UI and IO related events to be continuously serviced without overly complex synchronization strategies, keep the UI responsive while managing the IO polling needed to support both of my planned operations; UDP network communications and graphical UI events.

Many more details to layout, but we have a working example in the github project referenced above.




SknServices: An Alternate Development Strategy for Rails Applications


SknServices Strategy

Introducing SknServices

This github hosted Rails 5 project, https://github.com/skoona/SknServices, is an small example of core authentication and  authorization security processes; and a real example of an alternate development strategy for Rails based web applications.

Rails enables an MVC-based Web Framework.  The MVC pattern is a classic and used with success, as is, for many applications.  However, there are many maintenance, scaling, and growth issues when the code set exceeds a certain size or feature mix.  We understand these growth issues and have chosen to apply a more traditional Domain Driven Design bias to implementing applications using Rails.  Bias here means to loosely align with DDD and OO principals, but we do whats needed to get the job done.

SknServices strategy involves treating all of Rails as a Web Library for our application.  Ordinarily you would not write your application by embedding it inside a library of any kind, so a rethink of the Rails Way is required.

ReThink: How would you structure your application differently if you chose not to embrace MVC?


SknServices metaphorically takes one step back from the Rails MVC Way.  Rather than add code to controllers, views, and data model we implement a classic OO application structure; right now we refer to it as a Service Strategy.  

To make the connection back to Rails: 
  1. Router/Controller entry-point methods must make one call to an application service, and that application service will return one bundle of results data packaged as a ResultsBean.  The results bundle will generally have three keys; #message, #success, and #payload.
  2. Views accept the #payload and expect to find booleans telling it which page elements have been authorized for display, and the data as basic ruby values/objects need to populate on-screen elements.
  3. Several Application Helpers have been created to bridge between the application and the controller or view methods.  This enables application services to convert named routes, etc without have direct knowledge of the controller or ActiveView.
This now means that authorization, feature logic and flow, etc has to be done is our application through one services method invocation per request.  Shouldn't be a surprise, this is where our code goes. 


To enable the controller to find our services, a #service_factory is added to the base ApplicationController, a #method_missing? implemented to handle delegation.  This ServiceFactory contains the initialization methods for all services, adapters, and provider classes in our application.  All SknServices components have access to this central ServiceFactory.  

The service method invoked from the controllers entry-method is defined in a ProcessService class.  The rethink allows us to gather page level feature methods into one class, it should be natural to combine them by the process they are related too.  AccountService, PolicyService, QuoteService, ContentService, MessageService might be names that your application would create as ProcessService class names.  These methods are required to:
  1. Parse the incoming params, collect and package the resulting data into a ResultsBean for the controller/view.
  2. Alway return a proper answer to the controller, which requires it catch any exception thrown by lower level routines
  3. Call one domain level method, through inheritance, to generate response data.
As indicated a ProcessServices class inherits from a ProcessDomain class.  Domain classes have a collection of methods that actually do the work to generate a valid and pre-authorized response for this application entry-point.  Again these methods are likely topical and related to a single business process.  If ActiveRecord/ActiveModel work is required for this process step the domain method will call the appropriate data provider through the service factory to retrieve the business object needed.  Providers return only business object; never a AR record instance, just attribute bundles.  If part of the process step work requires specialized processing, a TaskAdapter may be invoked to complete the work needed for this request.  All processed results are returned to the service methods and packaged for the view.

Role-based authorization, Profile-based content authorization, and Warden/Rack-Attach Authentication were also implemented as Rails independent components.  The example application is a minimal shell highlighting a content authorization strategy for protecting downloadable assets.  You will find that regular Rails CRUD is still used in some places, but the majority of the app uses the Services Strategy.

This is how I refactor Rails code.  If this has your interest, read the code in the github project.  It also includes a PDF with specific guidance for what to expect in the code.

I'll update this post with more details.  For now, let me know your thoughts in the comments.


James,