Wednesday, July 15, 2015

JQM: A mini MVC Application Structure using jQuery Mobile and RequireJS

The Rational

When it comes to the power jQuery Mobile (jqm) to help us organize our code we could pretty much say it in one hyphened word: "non-existent".
How could this pass with such a popular library. Well, the simple answer is that it is by design. This does not mean, however, that you should not organize your jqm code projects. You are free to use any JavaScript organizing principle or helper library, e.g. BackBone or Ember, you like. Jqm's  focus is the page paradigm and rendering of touch friendly UI.

This, of course, does mean that you have your work cut out for you to make decisions surrounding your project. Looking at very common pattern of jqm apps, they tend to be an amalgamation of different libraries that have many layers of code and logic that needs to be organized. And, needless to say, there is always seems to be a little bit of overlap in library's coverage, e.g. if you used Backbone for route handling, we will need to turn off the native jqm methodology etc.

In the particular approach I am outlining in this post, the goal was to use minimal amount of libraries while still creating convention based organization of code, ui, and data. We should be able to split our program into distinct parts that the browser can load when needed.
This will help us in following manner:

  1. decoupling of presentation and logic
  2. modular JavaScript code
  3. decoupling of the page paradigm from singular page apps
  4. organization of code by convention


Overall, the maintenance of our program should be easier, while adding new parts becomes child-play ;o)

After a little experimentation, I decided the only thing needed was a little extra JavaScript and the RequireJS library. Let me explain how.


The Setup

Standard application initialization occurs through the index.html page. However, unlike most JS apps there is only one <script> tag and that tag loads RequireJS. Thereafter the application parts are either loaded by RequireJS or JQM page loader. Thus, the script tag jungle is avoided. Clean abstractions of dependencies and libraries are all captured in the RequireJS config file.

Since this is a sample app it makes liberal use of console.log function.

    <script data-main="app/config" src="libs/require.js"></script>        

Also something that is different here is the externalized page header. I did not add an externalized page footer which can be easily done but was not needed for my example. An externalized header can easily be repeated on each subsequently loaded jqm page and thus we can focus on the page content. We will still change the header display dynamically and add proper navigation as we move between pages.

<!-- external header used on all pages we will hide buttons dynamically -->
<header data-theme="b" data-role="header" data-title="Simple App" data-position="fixed">          
    <a id="btnHome" data-rel="back" data-transition="slide" 
       class="ui-btn ui-shadow ui-corner-all ui-icon-arrow-l ui-btn-icon-notext ui-btn-inline" 
       title="move back">back</a> 
    
    <h1></h1>

    <a href="#info" id="btnInfo" 
       class="ui-btn-right ui-btn ui-btn-inline ui-btn-icon-notext ui-mini ui-corner-all ui-icon-info" 
       title="">Info</a>
</header>


The Application Structure

The application is structured in such a fashion that a certain convention can be observed.
The main directories under /app are

  • controllers
  • data
  • pages
  • services
  • stores



All code files except the RequireJS config file are in a slightly modified JavaScript AMD Module format.We are also caching jqm views (pages) once they have been loaded using the jqm domCache directive:
$.mobile.page.prototype.options.domCache = true;


controllers

This is where we place all controller logic for our views. I maintained a convention where views do not have any logic or binding and minimal links. Controllers are automatically loaded and initialized based on the view (page) that is being requested. The app will check for a similarly named controller and start the process. Thus, all page behavior, event binding, business logic would be handled here.

If the controller exports (or exposes) a function named "init", that function will be called after each page load or display.

The overall convention for the controller loading process and application behavior are coded into start.js module. It acts as the overall controller for the application.

Here is the basic controller construct example.

//controller sample
define(
    function() {

    console.log("empty controller loaded");

    //public (export)
    return  {
        init: function(){
            console.log("init was called")
        }
    }

});

data

I have placed a file containing a json array of objects into this file. Thus, we can refer to this as our "database". This is not a convention that is enforced on the code layer. I chose to abstract data in this fashion. It could easily be extended to be the connection layer to a database API etc.

pages

The pages in our app are the view of the MVC model. I chose to use very simple views. These are snippets of HTML just with the JQM markup needed to render a basic skeleton. Logic that changes the view is either in controller or services layer.

Here is an example of a view. It is just the date-role="page" part of the jqm html markup.

<section data-role="page" id="composerDetail" data-title="Composer Detail">
    <div role="main" class="ui-content">


    <h2 id="composerName">Composer Name</h2>

    <hr>
        <!-- composer info -->
        <div class="ui-grid-a ui-responsive" >
            <div class="ui-block-a center" style="width:20%;">                
                <div class="">
                    <img id="composerImage" src="" alt="composer image" style="vertical-align: middle;"> 
                </div>
            </div>
            <div class="ui-block-b" style="width:80%; vertical-align: top;">
                <div class="ui-body ui-body-d"><p id="composerDescription">composer information</p></div>
            </div>
        </div>


        <!-- buttons -->
       <div class="ui-grid-a center" >
            <div class="ui-block-a" style="width:20%;">
                <div class="ui-body ui-body-d"><a data-rel="back" data-transition="slide" class="ui-btn ui-shadow ui-corner-all ui-icon-arrow-l ui-btn-icon-notext ui-btn-inline" title="Back to composer list">back to list of composers</a></div>
            </div>
            <div class="ui-block-b" style="width:80%;">
                <div class="ui-body ui-body-d">
                    <button id="btnWiki" class="ui-btn ui-icon-arrow-u-r ui-btn-icon-right ui-corner-all" title="More information on WikiPedia" style="width:80%">WikiPedia</button>
                </div>
            </div>
        </div>
    
    </div>
</section>


services

This is where I paced example services that can be used in other modules. In my case just a way to abstract jquery ajax calls and handle generic responses. But, this could be easily expanded to anything that is shareable across the modules or detailed implementation that would be make controllers large and unwieldy. This is not a enforced by code but a convention I am suggesting. It helps to separate heavy logic into distinct modules for maintainability.

stores

I used the stores to abstract interaction with the data layer. For example my sample ComposersDataStore.js in this project can sort the composers, return a specific one etc. This is also not enforced by code, but rather a convention I am proposing for your app build.

The Init Process

After loading of the index.html a list of dominoes begins to fall

  1. Require will load config.js which contains the environment definition and load dependencies. 
  2. config.js will, in turn, load the start.js module which contains our overall application controller
  3. config.js will also switch to the "main" page (view) which will trigger common actions by the overall application controller as defned in start.js
    1. Load the main view (main.htm)
    2. Load the main_controll.js controller
    3. Call the init function of main controller

Thereafter it is up to the user and his/her interactions which pages will be loaded and which actions will be triggered.

Unfortunately there seems to be a bug in the jQuery Mobile page loading (page widget) which makes initialization phase inconsistent. The process is not always kicked of correctly so it required for me to do a check in the index.html itself. If we did not find the main controller module loaded after 5 seconds, we would switch to the main view one more time, which triggers the part 3 and seems to fix things. This loaded the app consistently across all devices.

        setTimeout(function(){
            if (!require.defined("controllers/main_controll")) {
                console.log("catch all triggered.");
                $( ":mobile-pagecontainer" ).pagecontainer( "change", "app/pages/main.htm", { showLoadMsg: true } );
            }
        },5000)

The Hook

The element that drives the main convention of this app is implemented in the pagecontainerchange  event hook. This event is exposed by jQuery mobile.

$(document ).on( "pagecontainerchange", function() {}

Here we automatically load the appropriate controller based on the id of the view (page) and initialize and call the init() function of the module. In addition, we change display name of the view based on what is in the data-title of the jqm view definition. All this happens in the start.js application controller. 

Of course, in a more opinionated implementation, additional conventions could be coded here; for example, automatic loading of data-stores and even binding of the store's fields to form elements. Thus, the concept can be expanded. Experiment and see if you could add to it.


GitHub baby

The complete project can be reviewed or downloaded from GitHub. I have included the libraries and versions of jQuery and RequireJS so things should be able to work out of the box:

Expanded Project for Download from GitHub

Enjoy,
B.



Saturday, May 23, 2015

App Idea: CircleDJ

The Idea


So you have music you are listening to, you like a piece of music so much you take out your ear-buds and press them on your friends to listen to the part of the song that you like so much. You guys start chatting about how cool the song is and how some other band is equally cool. You go back and forth pulling things from your individual play lists and having fun chatting about music and friendship.

The way you go about it seems rather old-school in the age of mobile tech, doesn't it? What if you had each an app loaded that could make this sharing easier, better and even more fun? What if you could comment on parts of pieces of the song as it was being played?  Even bring in other friends into a "circle" to listen to the same song as it is being played. No more sharing of ear-buds while being able to comment and recommend a dynamic playlist? Everyone in the "circle" could assume DJ duties, putting things on a queue or taking over playback directly?

Initial idea assumes that songs are owned outright by all participants, but alternatives are possible where this is build to work on top of premium subscription services that give people already access to all songs in catalog.

More Features


  • Users can invite friends into special purpose circles, e.g. School, Workout etc. 
  • You can see who is being DJ in which circle
  • Listening and comment history is available for circle members
  • Circle members can compare their song libaries
  • Allow in-app purchases of "missing" songs
  • Record snippets with comments to post on twitter or Vine

Techno Mumbo Jumbo

This is the section I am trying to sound edumacated.
  • The basic principle is based on synchronized playback (stream or local) of media  (audio or video) with shared playback control.
  • Dymanic content and control of media, e.g. different users can control speed, and location of playback and this can by dynamically changed either via an election or granting scheme.


Extensions


  • Build on a music streaming service, e.g. Pandora or Spotify
  • This idea of "social-sharing" and "active" commenting can be extended to field of  any stream-able media, e.g.Video. If you are wanting to do similar App on the basis of YouTube or other video streaming services.
  • Bots could partake in playback control to make recommendation to groups and playback parts or tracks.
  • The potential exists to "redefine" radio as we know it in this format. "Radio" users could take alternate control and "DJ" or curate for specific group or at specific times for other listeners. 
  • Feedback loop and control look can be build via twitter like services. If enough of a hastag is tweeted alongside another song specific hashtag, a bot can put the most on demand songs into the play-queue.

Social Implications


  • Circle songs and comments can be shared on twitter, facebook, etc.
  • Big Data: comments can be analyzed for trends (frequency language, power parts in songs etc.)
  • Song Ratings for activity types
  • Extract snippets to post with comments

Related Competitive Ideas


  • It would be expected that streaming services will build something like this into their apps to ensure higher level of stickiness for their premium services. This could be only available for premium subscribers, inviting others to their listening circle would require subscription. Or, in a modified form without the subscription you cannot participate actively (no commenting, no DJing)


Monetization


  • The assumption here is that everyone owns a copy of the song, if not friend that wish to listen in will have to purchase the song. An affiliate payment system can be used or direct resale of music.
  • Recomendation engines to build suggestion to the circle members for purchase.
  • Advertising (I do not like to mention this since this seems to be overused)
  • Subscription element to unlock features, e.g. ability to DJ for the circle
  • In app purchase of songs
  • DJs could be hired to remote play and interact


What are these post about

So, like seemingly, everyone I have been collecting ideas about apps that would be "next big thing" and promptly putting them on a shelf based on time and resource demands. I am fleshing things out in bullet points. Rough bullet points! You are free to do with it whatever tickles your fancy.

I have decided to break with the cycle of selfishness and just post the ideas for anyone to use. Though I am not opposed to gazillions and instant nerd-fame, I have come to the conclusion that I rather have the idea be turned into action when I know that I will not be able to.

Also I am sharing in the hopes that, even, if marginally, I am preempting the people that like to patent just about everything including how my shoe laces tie together from stifling innovation. This is prior art people. Booyah!

Do you expect a return?

In one word, yes! I am hoping that I get attribution credit or free coffee for life whenever one of these makes it big. You don't even have to tell me, just send me my platinum Starbucks card!

Fool, this already exists!

If such an idea has already been turned into reality, the world is a better place ! Share it in the comment section. I do not do exhaustive research though I try to look through the app stores trying to find apps with these features. If you think my ideas are a bunch of doodoo, no need to comment, just create better ideas and make the world an even better place.


Cheers,
B.

Thursday, November 13, 2014

CF: Allowing different extensions for scheduled task log files

This is a quick post for people that run into this dilemma where there scheduled task stop working upon upgrade. They may receive this type of error in their browser:

Initialization Error: Valid extensions are : log,txt. - Invalid extension of the file name.

At first you go "What the Heck!". Then, look through gazillion lines of code to find where we could have produced this error and could not pin-point it.
Then, more digging to find the culprit:
With the advent of ColdFusion 10 & 11 and the exposure of the scheduled task vulnerability there was a change to what extensions where supported for your log files when you schedule tasks. As a security element these files can only be log and txt files.

However, the raw capture of the task run is normally neither, more often than not, especially with debug for the local IP enabled the output is HTML.
Thus, we have, now, for many years, used htm as the preferred extension, since the raw capture of the task run is HTML, thus, easy to view in the browser.  Forcing it into txt would only makes us rename the file before opening in the browser again.

Nightmares of unneeded code change ensued...

Fortunately, the solution seems simple enough.
a) Stop the ColdFusion instance
b) Find the neo-cron.xml
c) find the line that read like txt,log
d) add your extension to that line, e.g. txt,log,htm
e) start instance

Hope this helps others who give themselves the "Duh" slap.

Cheers,
B.


Friday, June 6, 2014

CF: CCFML or Making the Case for a Different CFML Future

Looking at the demands of our enterprise and the product road-maps as far as they have been disclosed by either Railo or Adobe we discovered a gap between what we are trying to achieve and what the technology is going to offer.

So, I have taken upon me to summarize a few thoughts and suggestions that I would like to share to see whether we can sway the Railo/Adobe general product direction.

I believe that focusing ever more innovation resources on the concept of RAD (Rapid Application Development) and language improvements, though interesting and useful, are not making CFML standout sufficiently to make a long-term difference and detract people from leaving or encouraging  new people to join.

In my opinion, the next level of server improvements need to be substantially different from other offerings and, this, in turn, requires a rethinking of what Railo/ACF offerings are.
Specifically,
Abandonment of the concept of Application Servers
Remove the need for download/installs
Remove the need for server administration and management
Redefine offering as packaged “infrastructure” with smart policy and deployment
Use clear convention based guidelines for subsystems (cache, application, storage, db)

Ok, now you say, what the heck are you dreaming about?
Good question, that.

In short, I am proposing that we work towards a true Cloud CFML platform === CCFML.

Let me explain:

We come from a heritage of dealing with individual servers and have embraced that concept wholeheartedly for many years. However, in the age of the cloud we should question those expectations.
How much more attractive could CCFML be when you only need a github/subversion account to deploy your code and a few policy definitions on how large you want your Application to scale and how fast.
When there are application problems, you can define policies how much CPU a process may consume, add more CPU cycles specifically for it, and/or cache. All automatically.
You application works automatically, fully scalable, across the globe on CFML.
You are kept abreast of any problems, bottlenecks and are given options to upscale CPU, refactor code, or add instances. But, best of all, you let the Cloud CFML take care of everything that a global CFML service should.
You want to push a new version, just change code and click deploy/schedule button.

Whatever decisions need to be made to get us this platform nirvana should be in the forefront of cfml future enhancements. This would require more standardization of convention so that we can have auto- configuration over coding whenever possible.
Behavior for deployment will need to be defined and “standard conventions” documented.
Here is just a selection of things that need to be answered on the way towards such a CCFML platform:
- Which distributed cache to implement and deploy
- Deployment system magic (version, install, upgrade, start, stop, pause engines)
- How do you scale session across servers
- How to communicate among cluster members
- How do you join servers to clusters
- How do you create a unified lightweight Application scope across the cluster,
- How to measure and set time,
- How to define and use a shared file-system
- How do you delineate code files storage vs. user assets
- How do you provide Application policy definitions for scaling
- How to manage and analyze code performance
- Create Application Manager (instead of Server Manager)
- Assigned Server roles, e.g. stateless vs. statefull servers
- Global logging and analysis
- Etc., etc.
There are probably many elements I don’t quite understand or have not considered. This is where I would ask for the smart people of the community to jump in, but, the point I am trying to emphasize is that future innovation should be directed towards creating such a platform rather than focusing on the minutiae of the language syntax.

The CFML language is quite mature and tweaks on syntax can only have limited impact on stopping developer attrition while an easy to use application platform has the potential to attract developers.
This model also provides a clear path for providers of this tech to charge for the services with the value recognition they are looking for.

The good news is that we have many components already; the next step is to create the working package and provide CFML as a first class cloud service.

We would not be the first, others like Microsoft with Azure and .net and the Java/Scala Play! Frameworks have already started the thought model and are getting traction. I fear that if we hesitate too long we may miss an opportunity to reverse course.

I hope this is not too confusing of a ramble and I am looking forward to feedback.

-Bilal

Friday, October 25, 2013

AWS: Cache Me If You Can! Getting Started with Elasticache.

Here are the presentation slides from our monthly Charlotte Cloud Computing Meetup and AWS Charlotte Meetup meeting.

Application cache has the potential to tremendously speed up your response times. Putting a cache infrastructure together on the other hand may not be for the faint of heart. 
In this meetup we will investigate the use of Amazon ElastiCache. Amazon ElastiCache is a web service that makes it easy to deploy, operate, and scale an in-memory cache in the cloud.

Cheers,
B.

Friday, June 28, 2013

AWS: Amazon CloudSearch -- Find This!

Since we experienced some issues with this month’s meetup I am publishing the presentation slides here.
We may be able to run through this at a different time again.

From our meetup description:

So you have used SOLR and think that is the only way to go for anything search related. But, (isn't there always a but?) you are tired of maintaining infrastructure or attempting to scale this thing. 
Well time to look at alternatives specifically made for the cloud. 
In this meetup we will look at AWS search, which is based on A9 search technology acquired by Amazon. It does all the dirty work for you so you can focus on your facets ;o) 
We will discuss the good and the bad while attempting to use examples and build a search domain.


Cheers,
B.

Thursday, April 4, 2013

CF: Railo: Using VisualVM tool to monitor running Railo servers

I had written a Adobe ColdFusion specific article on how to use the free VisualVM tool to get insight into the workings of the Java Virtual Machine. I have since been asked to provide similar guide for Railo CFML engine.



The good news is that the implementation is very similar and mostly follows the same path. I will demonstrate this using Windows OS example. I assume in this example that you have used the standard Railo installer for windows.


If so, here are some simple steps to use this great tool set working with Railo.

1) download java jdk also referred to as Java SE Development Kit. You can use 1.6.38 or later or 1.7.13 or later.  Again, Important to get the JDK not the JRE.
http://www.oracle.com/technetwork/java/javase/downloads/

2) Download Visual VM:
https://visualvm.dev.java.net/

3) Configure Railo jmx access:
On Windows, best way is to go to Tomcat Service Control, open the Java panel and add the following to the Java Options text box: (you can change the ports etc. this is is my sample):

-Dcom.sun.management.jmxremote.port=8701
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false




You can decide whether to use ssl or not, and also on the port to use. If you want to use jmx authentication I would recommend you read:
http://java.sun.com/javase/6/docs/technotes/guides/management/agent.html#gdenl

You will need to restart your server after you have completed your changes.


4) Configure your Visual vm start up to point to your jdk if you have not set environmental variables:
e.g. on Windows
if you extracted the visualvm files into C:\visualvm135
and
Your JDK is located in C:\Java\jdk1.7.0_13
then you can use the following command line:

C:\Java\visualvm_135\bin\visualvm.exe --jdkhome "C:\Java\jdk1.7.0_13"

You can also add a batch file shortcut for reuse, e.g.


5) Start up the VisualVM tool (it may have to go through calibration first, simply acknowledge), then, and establish a connection a JMX connection by right clicking on the local node and choosing "Add JMX Connection..."


6) Add connection parameters:
If the server is local you can use: localhost:[port] in our case: localhost:8701



Now you should be able to monitor basic statistics of your Railo environment as it runs, and do some nifty things like forcing garbage collection and dump heap files for later analysis.

Cheers,
B.