our-foc.us

Early this year I wrote a simple to-do planning web app in Clojurescript mostly for use on my smartphone. As a learning experiment with client/server side Javascript and Meteor I rewrote it to support real time collaboration: our-foc.us

This was an interesting learning experience, and I must say that Meteor if both easy to use and provides impressive functionality “out of the box.”

Recent disclosures on NSA data collection

I was going to not write about this because I believe that everyone should do some research and make up their own mind.

That said, I think that the recent disclosures might end up being as important as Daniel Ellsberg’s whistle blowing over the facts behind the Vietnam War and the likely illegal acts of some people in our government.

As citizens of the USA I believe that the best we can hope for is more transparency in our government and overturning parts of the Patriot Act such as the FISA gag-order laws that have no place what so ever in a free and open society.

Here are a few articles on this subject that have high ranking today on Hacker News:

Court finds NSA surveillance unconstitutional. Administration’s response: keep the ruling secret and carry on

Google official blog: Asking the U.S. government to allow Google to publish more national security request data

Tim Berners-Lee: NSA Surveillance an ‘Intrusion on Basic Human Rights’ Note: Tim Berners-Lee invented the world wide web.

Edit: June 17, 2013: This is a good interview with three retired senior NSA staff who seem to support the idea that the recent disclosures are “whistle blowing” and serve the public interests.

It is good to get suggestions from readers: Meteor Javascript framework

I was writing about evaluating different UI frameworks last March and a reader named Amanu posted a comment about Meteor. I took a quick look at Meteor in March and then put a full eval on my TODO list (a simple little app I wrote in Clojurescript). I got back to doing a full eval this week (I have a long TODO list :-) ), and I must say that I am impressed. The documentation is good and I bought a short book that got me started in a few hours. For applications requiring shared state between multiple users Meteor really looks good. The development environment is especially nice because changes to code, HTML, CSS, etc. get automatically pushed to the browser. Meteor defaults to using MongoDB and manages a mirrored copy of a MongoDB data store in your browser with fine controls over what data is synced between server and client. Meteor is not magic, but close to it. Really nice work!

Automating Clojure web app deployments

I have several web apps written in Clojure with Compojure and Ring. Until today I used a manual process that used an rsync.sh script that took me a minute per deploy. Yuck! Today I implemented two different two methods. One requires a manual “make deploy” command and the other uses a local git hook on my development laptop for an automatic deployment. Both of these methods also use my old rsync.sh script to copy changed files, but the process is automated.

Makefile

I added a deployment target to the project’s Makefile:

deploy:
      ./rsync.sh
      ssh nonroot@MYDOMAIN.com 'bash -s' < run.sh

This assumes that you have an account "nonroot" on the server that you run web apps with. The run.sh file kills the old web app process and starts a new process; the file looks like this:

#! /bin/bash

ps aux | grep -e 'MYAPPNAME' | grep -v grep | awk '{print $2}' | xargs -i kill {}
(cd APP_DIRECTORY; nohup lein trampoline run prod > out.log&)

Substitute the name of your app for MYAPPNAME: go to your server and run "ps aux" and find a chacter string that uniquely identifies the process that needs to be stopped. Let me make this clear with an example. On my sever I did a ps aux and see the line:

nonroot 10444 0.0 7.0 1438456 95484 ? Sl May30 3:13 java -classpath /home/nonroot/knowledgebooks.com/test:/home/nonroot/knowledgebooks.com/test:/home/...

Here I would substitute "knowledgebooks" for MYAPPNAME.

I use lein with trampoline to run my web apps. I run Ubuntu on my servers and the killall command works fine. You will want to manually test this on your server and/or read the docs for killall.

Using a git post-commit hook

For some projects I don't want a separate step of running "make deploy" so I create a local git post-commit hook. I start by creating the file (and setting execute permissions on it) ~/.git/hooks/post-commit that looks like:

./rsync.sh
ssh nonroot@MYDOMAIN.com 'bash -s' < run.sh

This file post-commit uses the same run.sh file that I use for Makefile deployments.

Now, when I do a git commit, the deployment to my server is automatic.

If you are not familiar with using rsync, here is a quick start. My script rsync.sh (in each project directory) looks like:

rsync -e "ssh" -avz --delete --delete-excluded --exclude-from=./rsync_exclude ~/GITHUB/MYAPPDIRECTORY nonroot@MYDOMAIN.com:/home/nonroot/MYAPPDIRECTORY/ and the rsync_exclude file looks like:
.git
myfocus-clj.i*
target

Free mentoring help: what you need to do

You may have noticed the Free mentoring and advice page on my main web site. I am not really offering advice on business and marketing since that is not my specialty. I expect people to ask for help (mostly just having a conversation with me) on technologies that I use and write about; for example: Ruby, Clojure, Java development; web app frameworks that I use and blog about; text mining and natural language processing; semantic web; knowledge management.

I have had a few cases of people contacting me without putting much thought at all into what they want to do, who the customers for their project are, etc. I am very busy and I am serious about limiting our conversation (either via email or on Skype) to one hour so it is important to do the up front work of at least trying to answer the five issues/questions I list on my mentoring page.

My version of Ember.js ‘Get Excited Video’ code with Sinatra based service

The Ember.js Get Excited Video has source code for the example in the video but the test data is local on the client side. I forked this project and added a Ruby Sinatra REST service. My version is here. This uses Ember.js version 1.0 RC4. It took me some time get the example code working with a REST service so I hope my forked example will save you some time and effort.

complete (but small) DART client server example

Two days ago I blogged on DART. The problem with the example I showed two days ago is that it was two separate applications: a service and a service that launches a rich client app.

Dart_setup

Today I figured out how to have a single service that:

  • Returns the app’s HTML file that loads Javascripts and other assets for the route “/”
  • Services the REST APIs with the route “/api”
  • all other routes are assumed to be local files to read and send to the browser (like CSS, etc.)

This is not intended on being efficient (I read each file as I serve it, to pick up edits during development). Here is the modified server file file mlw_json_server.dart:

import 'dart:io';
import 'dart:json' as JSON;

main() {
  var port = 8080;
  HttpServer.bind('localhost', port).then((HttpServer server) {
    print('Server started on port: ${port}');
    server.listen((HttpRequest request) {
      final String path = request.uri.path;
      print("path = ${path}");
      if (path == '/api') {
        var resp = JSON.stringify({
          'name': 'Mark',
          'hobby': 'hiking'}
        );
        request.response..headers.set(HttpHeaders.CONTENT_TYPE, 'application/json');
        request.response..headers..write(resp)..close();
      } else if (path == '/' || path == '/index.html') {
        fetch_file(request, 'mlw_json_client.html');
      } else {
        fetch_file(request, path); // serve all other files like favicon.ico, etc.
      }
    });
  });
}

fetch_file(request, path) {
  print('* fetching path = ${path}');
  final File file = new File('../web/${path}');
  file.openRead().pipe(request.response).catchError((e) { print('error=${e}'); });
}

The client file mlw_json_client.dart is unmodified from my blog from two days ago.