Lately at work I have been using ColdFusion event gateways to accomplish a few very specific tasks. I thought it might be cool to see if I could leverage CFThread on Lucee do accomplish some of the same things.
The first step was writing a working demo with ColdFusion. A buddy was kind enough to point out that using an event gateway with a cfthread running inside of it was doing extra work for nothing. Event gateways were introduced before cfthread so I went ahead and just refactored it back as a regular ColdBox service. Everything was running smoothly in ColdFusion.
Next was trying to port the same code to Lucee since that is what I tend to run for personal projects. The one road block I did run up against is cfthread terminating at 50 seconds, the default request timeout for Lucee. It turns out there is a simple fix for it, but it made me scratch my head for a while since I didn’t run into it on ACF. The code with fix is below.
It was not a hard fix (setting the request timeout extremely large), but it did take a bit of google-fu to figure it out. Interestingly enough, setting the request timeout to zero did not work.
It seems that 2015 is coming to a close and I thought it would be a good time to compose my fourth and final post of 2015. It has been a slow year blogging but that is not to say I have not been busy.
Finally I have been working with GitHub’s Electron to build cross-platform desktop apps. Mostly this has been writing tools I can use for work since that would actually push me to learn Electron and Angular. Writing an application once and being able to build it for Mac/Windows/Linux is just awesome. My teammates at work have enjoyed the fruits of my labor.
Aside from that I have played a lot of games in 2015. I enjoyed Destiny for a while, but really my old standby is Diablo 3. I am excited to see what 2016 has to bring and I hope all of you have a happy and safe new year!
Lately I have focused a lot of my attention on Node.js, Express and Angular. One of the great things about Node is how extremely flexible the language is. However, when you are learning a new technology that flexibility can be a liability.
My first attempt at learning Node.js and Express was focused implementing framework paradigms that I would use developing a ColdFusion application. My application was a Diablo 3 character differ that would allow you to compare two characters side by side. It was a good lesson in how to structure a pure Express application. Plus, it worked, which was awesome.
Next I decided to focus on Angular and since I was trying to run it on a MEAN stack of course the first two projects I checked out were MEAN.IO and Mean.js. Both of these are really great projects, but when you are just trying to pick the stack up I was just completely lost.
When that did not pan out, I tried getting started with Node and Express using the same framework I used with the character differ. I was using Handlebars for server side render engine on Express which unfortunately conflicts with variables in Angular. Yes, I know you can change the brackets with $interpolateProvider, but I did not want to muck about changing things when I shouldn’t have to.
I was a little annoyed, but I was just going to develop the Angular portion of the app served with Nginx and write the API portion in Node/Express. I was taking a look at John Papa’s Angular style guide though and many of the configuration blocks just falling into place. Following John’s style guide along with his ng-demos repo I had my new Node/Express/Angular app up and running in no time.
If you have not checked those out, I highly recommend it. I might head back to MEAN.IO or Mean.js eventually, but I am enjoying learning the new stack for now.
ColdFusion has just turned 20 years old and I have been developing with it for 16 of those 20 years; almost half my life. I still use ColdFusion every day in my professional life, but I do not feel the excitement for the language as I used to. I can remember when I actually looked forward to the new features introduced with each new release, but those days have past.
A few weeks back we had a hackathon at work and this was my first real application hands on with Node. The project was an end-user level interface that allowed creating an issue and having Node interface with Jira through web services to create issues and assign it to the right project bucket. In retrospect, there definitely are easier projects to choose for your first Node project (especially when you are dealing with the learning curve and you have finite amount of time to get the project done). However, I did pull it off with about 15 minutes to spare. I didn’t win the hackathon, but I had a working Node project and a lot of insight in how to get things done in Node.
I started a little side project to continue learning Node, a Diablo 3 character comparison tool which allows you to compare two Diablo 3 characters side by side. This project focuses on a lot of middleware and making things work as well as hooking into the Battle.net API service. The project is structured much like a ColdBox app with routes, handlers and services. It is a work in progress and I am adding new things as I learn them. I have a demo up and running at http://diablo.kisdigital.com and the full source up at https://github.com/robertz/chardiff.
Next up is a look at Go (http://golang.org)
It has been pretty quiet around here for a while so I thought I would go ahead and post a quick update and get my first post in for the year. There have been quite a few things keeping me busy lately and the day job keeps me busy more often than not so here is my current list in no particular order.
If I loved ColdBox any more I would probably have to get a room. I have been playing with CB4 since the bleeding edge releases but I have switched some of my 3.8 projects over to 4.0. A lot of hit has to do with compatibility since the core was cleaned up.
Google OAuth 2 Integration
Having to rewrite user authentication for every application seems a bit of a drag, especially when user authentication can be handled by somebody else. To that end, I am looking to have Google handle all my user authentication going forward. Ray had some code for hooking into Google’s OAuth2 implementation and I am working on getting that wired in to CB4.
Lucee Application Server
I have used Railo for years and I was sad to see it would have no more updates. Then Lucee was announced and I was cool again. I spent a few weeks tuning my installation process and moved away from the automated installers to custom installations. I have always been a bit of server geek so this was right up my alley.
I have been wanting to get in to Node.js and Socket.io for ages, but time has always been a factor. However, lately I have been looking into ways to leverage websockets aside from a chat application (I wrote one of those too) so I finally sat down and learned just enough for me to be dangerous. It was pretty easy getting socket.io to talk to the ColdFusion server through API calls. Next will be figuring out how to get CF talking to node.
The WordPress.com stats helper monkeys prepared a 2014 annual report for this blog.
Here’s an excerpt:
The concert hall at the Sydney Opera House holds 2,700 people. This blog was viewed about 44,000 times in 2014. If it were a concert at Sydney Opera House, it would take about 16 sold-out performances for that many people to see it.
Recently I have moved all my development to Vagrant virtual machines to avoid having to setup a dev environment on my local machine. Mark Drew has an excellent article on how to set this up. My setup is modeled very close to Mark’s setup however I setup Nginx as a reverse proxy back to Tomcat as this models my production environment.
Hopefully this will help someone out because I know I was pulling my hair out on this one.
I am working on a project that will eventually require a login. That being said, it would be nice to always have information for the currently logged in person stored in the PRC. ColdBox has a built in class fittingly called RequestContextDecorator which will easily handle this.
Here is a basic request context decorator:
There is not a lot going on here but I will cover the basics. First, a request context decorator must extend coldbox.system.web.context.RequestContextDecorator. Next a configure() method is required that will modify how the request contexts behave once they are created. Getting the original request context is handled by calling the getRequestContext() function and additionally you can get the private RC by calling getRequestContext(private = true).
Now you can modify the RC and PRC with any values you like. For extra points I have included getting ColdBox settings as well as getting an instance of a service through Wirebox.
I have been using ColdBox for quite some time but the other day I decided to step out of my comfort zone and try to learn some new things about the framework. Interceptors are a feature of ColdBox that look really interesting but I have never looked into so I thought it would be a good time to check it out.
Quoting the documentation on the Wiki, interceptors are “ to increase functionality for applications and framework alike, without touching the core functionality or events, and thus encapsulating logic into separate decoupled objects.” This functionality can be bound to specific events in a request cycle and even create custom interception points and call those events with the announceInterception() method. Awesome stuff!
One of my first open-sourced projects I did was a utility called WhosOnCFC and I thought it would be a good starting point for my first ColdBox interceptor. When a browser views the web site it checks an internal list of the known clients and if the client is not known it tracks some basic information on the browser such as IP address, current URL and the user agent. On subsequent page loads it will update the current URL and time. Traditionally this would be handled in Application.cfc in onRequestStart() so lets see how to handle this with a ColdBox interceptor.
This is the basic layout for an interceptor. The configure() method is required but as this is a very simple interceptor no additional configuration is needed so it is empty..
Next is the afterAspectsLoad() method which is triggered once the application has started. It is ColdBox’s approximation of onApplicationStart(). This is where the instance of WhosonTracker is created and set in the Object Cache Manager so it will persist between requests.
Finally there is the preProcess() method which will execute on every page load. The method will grab the instance of the tracker from the OCM and call the trackHit() method which is where the magic happens.
If you were writing your own interceptor you could bind to as many or as few events as you like. These two events will do for this example.
Now lets take a look at the component that will be doing the work for us, WhosonTracker.cfc. Basically, when initialized we create an array that will store our client data. The trackHit() method is our meat and potatoes. Every request it will check to see if the client is known and either create a new client or update the current clients information. It will also clear out any clients that have not updated in the last five minutes.
There is also a getData() method that our handlers/services can use to get a listing of clients we can output.
Finally we need to register our interceptor with ColdBox so it is executed. Once the application is reloaded the new interceptor should be called on every page request..
As you can see it is easy to create your own interceptors. I did some searching while trying to figure things out and there is tons of documentation out there and a few recipes on the ColdBox site for creating your first interceptor, but it did not really walk you through the process. Hopefully someone may find this useful.
The full code listing is available here: https://github.com/robertz/coldbox-salsa
There you can find some additional code such as the handlers and views to output the data. My development server removes the /index.cfm from the URL by default so if your server does not support SES URLs, edit /config/Routes.cfm on line 15 and add /index.cfm to setBaseURL().
Just a quick note, I have a project up on GitHub called MovieBox. This was based on keyStream by Cory Fail, but is built on top of the ColdBox framework. Right now it is in a holding pattern because I am going to rewrite it using AngularJS for the frontend and Taffy for the backend REST API. I have been wanting a good learning project for Angular, bower, gulpjs, et al so this will be my guinea pig..
This project does have some pretty good bits, it can scan a directory of movies and pull the metadata from themoviedb.org and update your library accordingly. You will need to specify the default location of your movie directory which is set in /config/Coldbox.cfc under custom settings. Currently the indexer does not run automatically, it must be forced by calling http://localhost/wtf/indexMovies. There is a SQL script for the database creation (mySQL format, but may work on others) to setup the database schema. It expects a data source named moviebox to be setup in the web/server administrator. Additionally, it is assumes the movies are stored as X:/movies/moviename or even better X:/movies/moviename (year).
All videos should be available to the web server under the /media directory. Assuming you are using Nginx as the front end proxy it is an easy as creating an alias in your site definition, but it should be easy enough to do in other servers.
If your server does not support SES URLs you must edit the /config/Routes.cfm and add “index.cfm” to the setBaseURL() line. Also, I would definitely recommend using the development branch as it is the most updated (and also contains the SQL script for database generation).
Aside from that, everything should work great. 🙂 The indexer will attempt to download the movie poster and backdrop and will copy the data into the movie folder as well as the data folder under the web root. If the data folder does not exist it will be created for you. If you have a lot of data, expect the initial look up to take a while. Subsequent scans will ignore titles that are already known.
You can check it out here: https://github.com/robertz/moviebox/tree/development