Launch an App Month – Simple WorkFlow task manager

Over the weekend, someone over on Hacker News posted a challenge – Make November launch an app month.

I have a day job in a ‘large enterprise’, so to get an app launched by November, even the end of it, it would need to be small enough to go from concept to minimal viable product in just under 2 months of evenings.  From past experience, if I cannot get a viable product going in that time, I will lose interest and abandon it, so picking something small is even more important.

I have been searching for a new project for a while, and was recently inspired by email overload while managing simple tasks in my day job, which gave me an idea for a new project.

Application Idea

In any large enterprise, there are different groups of people responsible for different systems and different teams responsible for different parts of the same systems.  For example, Application Support are responsible for the day to day running of the system, the DBA team look after low level database related things.  The release management team install code, Application Support run scripts and reports, etc.

To achieve any non-trivial task on a system, often several teams need to be involved and co-ordinate tasks one after the other or in parallel between teams (eg shutdown the application, backup the database, create a new tablespace, upgrade the application …).  Then there are the managers and delivery managers that need/want to be kept informed along the way, not to mention auditing the output of commands etc.

These problems don’t just occur during code releases either – when the enterprise goes into crisis management mode, often many teams have to carry out daily manual work arounds that need to be coordinated and reported on by even more anxious managers.

Where I work, this is managed with a mish-mash of phone calls, emails and spreadsheets.  So that got me thinking, what *my team* needs to make this easier is a very simple work flow app.

Requirements

The application would:

  • Allow a ‘task owner’ to create a task plan
  • The task plan would have a title, overview of its purpose and start date and time.
  • The task owner can add a series of tasks to the task plan to be executed in series or in parallel
  • Each task would have an implementer, instructions and perhaps file attachments, like scripts to execute etc.
  • Once the date and time for the plan is approached, the app would email the implementer (and any subscribed interested parties) the details of the first task.
  • Upon completion, the implementer would enter any log messages or relevant information and mark the task complete (this could be done by replying to the original email to save actually logging into the app).
  • The app would then email the next implementer and interested parties and so on until all the tasks are completed.
  • Afterward, the log of the event can be kept around for as long as required.
  • Interested managers can chose to subscribe to updates on the task plan on a task by task basis or at the start and end of the task as they see fit.

Now, I am pretty certain that if I looked around the inter-webs, a product just like this would exist, probably something hideous like ‘Oracle Work Flow Manager’ or something from PeopleSoft or SAP with more bells and whistles than Santa’s sleigh.  My aim here is to make a *simple* work flow app with as few features a possible to solve simple work flows.  If your problems involve flows charts and branching decision trees, this idea is not for you!

The requirements above are probably the minimum necessary, but there are tons on potential features that could be added if the product got some traction.

So what do people think?

Would you use an app like this?

Does it sound useful?

Are there lots of tools out there already that do something just like this and are easy to use?

In a few days, I hope to post a html mock-up of some UI ideas in an effort to crowd source some feedback on my idea before really digging into code.  If you are interested please subscribe to my RSS feed and I will try and build this product out in the open.

October 10, 2010 at 11:39 pm Leave a comment

Sub directories for STI models in Rails

I recently started using Single Table Interitance in my Rails application and immediately wanted to group all the child models in a sub directory inside the models directory.

All over the web, the advice was just create a directory, stick your models in there and then add on of the following into environment.rb:


config.load_paths += Dir["#{RAILS_ROOT}/app/models/**/**]
# or
config.load_paths += Dir["#{RAILS_ROOT}/app/models/mysubdir"]

Well, this doesn’t seem to work, as of Rails 2.3.2 anyway (no idea about earlier versions).

It seems that Rails scans the models directory, and when it finds subdirectories in it, it loads the classes into a namespace that is the subdirectory name. If you have a subdirectory called Actions, your classes will end up loaded as Actions::SubClass, which is not want I wanted.

To get this working, I had to put the extra load path I wanted at the front of the load path array (at least before it loads the models directory):


config.load_paths.unshift "#{RAILS_ROOT}/app/models/**/**"
# or
config.load_paths.unshift "#{RAILS_ROOT}/app/models/mysubdir"

I am not really happy with this approach, but I have already wasted hours trying to get it working at all, so the hack will have to do for now!

April 10, 2009 at 6:02 pm Leave a comment

Code Comments are not for tracking changes

Recently, I have been reviewing and correcting a lot of broken code, and in doing so, I have concluded that the number of developers who know how to properly use a bug tracker and version control is not nearly high enough (disclaimer – this is in a big faceless corporation).

Commenting Anti-Pattern

So what leads me to this bold conclusion? Have you ever seen code that looks like this:

begin
  -- start change for #3245
  v_myvar varchar2(100)
  -- end change for #3245

  for r in (select c1,
            /* start change for #9870 */
                        c2,
                        c3
            /* end change for #9870 */
              from foo_table
              where c1 in (1, 4, 6)
           -- commented out for #9870
           -- and c2  = 'val1'
           -- start change for #5678
               and c3 = 'val2'
           -- end change for #5678
             ) loop
    null;
  end loop;
end;

Ignore the fact that this code does nothing useful, and is PLSQL – its just there to illustrate a point.

The amount of code I have seen recently that has its changes tracked through inline comments that attempt to encapsulate every single line changed to fix a bug or add a feature is unbelievable.

Some may ask, what is the big deal? Well firstly, when I see code like this, it says to me, the developer who did this, doesn’t have any idea about version control – they are commenting every change to attempt to provide traceability and rollback ability to their change. Often, when I see this anti-pattern, I subsequently find the code hasn’t seen the inside of Subversion or anything like it.

Show me the code

If I ever dare to ask to see the changes that were made to fix a bug in code like this, I get handed a source code file and told to grep through it for the bug number – what scares me, is how do I know he remember to comment every single change? For a big change, it takes a lot of patience to do something like that! And then the Delivery Manager (DM) arrives at the developers desk and the conversation goes like this:

DM: Remember those 10 feature requests we agreed to deliver tomorrow, well how are they going?

Dev: No problems, we have them all finished and tested, ready to roll!

DM: Well, we have a problem – turns out the front end developers have not been able to complete feature #4567 and that impacts us – we need to deliver the other 9 changes, but not that one.

Dev: Huum, thats going to be a problem, #4567 was a big change – I don’t think we can get it out of there without a lot of effort!

DM: Don’t you have all this tracked in your version control system … back in my day we committed individual changes into SCCS and things like this were never a problem!

Dev: Gulp … guess its going to be a long night for me then sir …

Finally, don’t even get me started on how much harder the code is to read with all these annoying ‘starting/ending’ change comments.

A simple recipe

If you come across this rant, and have found yourself doing this, then stop a moment to think about how to use version control to track these changes for you – thats what is was designed for!

Here is a tip – when you have to fix a bug or add a feature to existing code:

1. Checkout your code
2. Make changes to whatever files are necessary and forget about pointless start/end change comments.
3. Get your test suite to pass your bug/feature (you have a test suite, right?)
4. Check in you code when its all done, quoting the bug number in the commit comment

Simple, clean code changes, traceable in a much more robust way and you can safely roll back the changes to any bug at any time.

The biggest mistake I see developers making with version control, aside from not using it at all, is to fix about 10 bugs, and then do a commit – please don’t do this, as it removes the ability to examime the changes made to fix a single bug, not to mention removing the changes if the need arises – which happens more than you may think, as our poor Dev found out above!

September 16, 2008 at 10:19 pm 2 comments

sqlite3-ruby-1.2.2 is broken on OS X

So I just spent ages trying to figure out why the latest version of sqlite3-ruby wouldn’t run on OS X. Turns out there is a bug

If you are getting an error that looks like:

dyld: NSLinkModule() error
    dyld: Symbol not found: _RSTRING_PTR
      Referenced from: /usr/local/lib/ruby/gems/1.8/gems/sqlite3-ruby-1.2.2/lib/sqlite3_api.bundle
      Expected in: flat namespace

    Trace/BPT trap

Its best to revert back to 1.2.1 which seems to work fine. This behavior occurs on Tiger and Ruby 1.8.4.

August 14, 2008 at 9:58 pm Leave a comment

Rails style meta programming in Ruby – part 2

This is part two of this blog post – if you landed on this page, then please checkout part 1 before reading this part.

Last time, we learned that all methods are executed by sending a message to self, where self is set to the appropriate object automatically. We also learned that class definitions are code which is executed at run time, and that a class is nothing but an object of type Class.

What is a metaclass?

Here is the next important point – Classes are a place to store instance methods, objects are a place to store instance variables. An object cannot store a method, only a class can.

But what about class methods? We know that a class is just an object, and when you say something like

class Foo
  def self.hello
    puts "hello"
  end
end

Foo.hello

You are invoking the hello method on the instance of the object stored in Foo, which happens to be an object of type Class (ie your class definition). So where are these class methods stored?

When you invoke a method on an object, Ruby looks at the object’s class pointer, which contains a reference to the ‘class object’ that defines the class. The class object contains the list of methods defined by the class definition, and a pointer to its super class, which contains another list of methods and a pointer to its super class and so on. Ruby searches along this chain until it finds the method it requires, or calls method_missing if it cannot.

To be consistent, a ‘class object’ should behave in the same way. It has a class pointer that points to a class. Ruby magically creates this virtual class when you define a class method, and uses it to store all class methods for the class. This magically created virtual class is what is known as the classes metaclass.

Note that metaclasses follow the same inheritance chain as classes, inheriting from metaclasses up the chain, which is why this works:

class Foo
  def self.hello
    puts "parent says hello"
  end
end

class Bar < Foo
end

Bar.hello

Classes can have instance variables

So if a class is just an object, and an object is a place to store instance variables, then can a class have instance variables too? Yes it can, but think carefully about how to access them.

Normally, we create a class, say Foo, and in that class defintion use attr_reader to provide methods to access the instance variables. So where do we put our attr_reader defintion to allow access to a class instance variable? We have to put it in the objects class defintion, which in this case is the classes metaclass:

class Foo
  @class_instance_var = '1234'

  class<<self
    attr_reader :class_instance_var
 end

  def hello
    puts "hello"
  end
end

puts Foo.class_instance_var

To complete the picture, we just need to know what the following syntax means:


class<<self
 ...
end

'class<<obj' allows us to extend an object by "building a new class just for object obj". In the context above, it basically changes self to be the metaclass instead of the defining class.

Another way of thinking of it is simply that 'class<<obj' gives you access to obj's metaclass.

When we are in the metaclass, we can define the attr_readers required to read the class instance variables.

Finally some Rails magic

Now we know every we need to know make this work:

class User < ActiveRecord::Base
  set_table_name :silly_named_users_table
end

We know that when 'set_table_name' is execute, it is executed against self, which happens to be the object defining the User class, so its just like saying:

class User < ActiveRecord::Base
  User.set_table_name :silly_name_users_table
end

This means that the method 'set_table_name' must be in User's metaclass, or in the inheritance chain for it, which includes ActiveRecord::Base. We know its not in User's metaclass, as we didn't put it there, so it must be in ActiveRecord:

module ActiveRecord
  class Base
  
    def self.set_table_name (table)
      puts "setting the table name to #{table}"
    end
  end
end

class User < ActiveRecord::Base
  set_table_name :silly_named_users_table
end

In the Users class, we want to store this alternative table name - it needs to be stored in a class instance variable in the User class, which is simple (I will also add an attr_reader method to the meta class so we can test the code does the correct thing):

module ActiveRecord
  class Base
  
    def self.set_table_name (table)
      puts "setting the table name to in AR #{table}"
      @tablename = table
    end
  end
end

class User < ActiveRecord::Base
  set_table_name :silly_named_users_table
  
  class<<self
     attr_reader :tablename
  end
end

puts User.tablename

The above code does as expected - why?

When set_table_name is encountered in the User class definition, self is the class object stored in the constant User. It cannot find the set_table_name method method in User's metaclass, so it looks in the parent class, and finds it, but self is not changed to the parent class, its still the class object stored in the constant User that is how inheritance works.

When we set the instance variable in the parent method, self is still User so we are setting an instance variable in the User class object. Anytime we call a method against an instance of a User object, the method can access that tablename variable and use it to generate the correct SQL. How to do that is left as an exercise for the reader😉

December 18, 2007 at 11:27 pm 3 comments

Rails style meta programming in Ruby – part 1

For a long time now, I have pondered and wondered about just how Rails does what it does – surely such wizardy is well outside my basic Ruby skills – well not any more thanks to this presentation by Dave Thomas.

He explains all the concepts you need to know, so that you too can do things in your own code like:


Class Users < ActiveRecord::Base
  set_table_name :unconventional_name
  has_many :friends
end

Dave, I am sure, explains it much better than me, but the video is an hour long, and I had to watch it twice, so here, hopefully is the 10 (or 20) minute summary.

Everything is a method

First things first – every method you call in Ruby is run by sending a message to an object – even at the top level when you wouldn’t have though so:


puts "hello, world!"

In the above code, puts is a method with is executed by sending a message to an object. Infact, no matter which method you call on any object in your code, it is always executed by sending a message to the same object, ‘self’.


puts self.to_s
puts self.class

prints


main
Object

So, at the top level, all messages are sent to an object contained in the variable self that is called ‘main’ and is of class Object.

When you type something like


  a = Array.new
  puts a.class

It prints ‘Array’, as the variable ‘a’ contains an instance of an Array object. The trick to remember here is that the ‘a.’ says, set the value of self to the object a, and then execute the method on self. This means that everytime you execute a method, it is always executed as a message passed to ‘self’, which will have been set to the correct object.

That is why this works:


class Foo
  def hello
    there          # a method call with no receiver?
    puts " there"
  end
  def there
    puts "hello"
  end
end

b = Foo.new
b.hello

When you are inside an instance method, executing another method without a class or object prefix invokes the method on the object self. Ruby arranges so that the value of self inside an instance method is the correct thing – ie set to the instance of the object the original method was invoked on, in this case the instance of Foo stored in ‘b’.

The following code is equivalent to the above, but self is explicity specified.


class Foo
  def hello
    self.there          # a method call with a receiver?
    puts " there"
  end
  def there
    puts "hello"
  end
end

b = Foo.new
b.hello

I know this seems trivial, but its very important, so I will say it again – a method is always executed by sending a message to self – self is always changing so it contains different objects however.

Class definitions are executable code

Big deal – what has this got to do with this spiffy ‘has_many’ Rails style directives. Well, the next thing you need to learn, is that class defintions are executable code. Remember that any method that is executed, must be executed on self …


class Foo
  puts "hello"

  def bar
  end
end

Classes are just objects

Runnning the above code prints “hello” – we know its doing this because class definitions are executable code, but also that puts is invoked against self, so what is self?


class Foo
  puts self
  puts self.class

  def bar
  end
end

Which outputs


Foo
Class

So inside a class definition, the current object is set to an object with the same name as your class, that is of type Class. This leads to the second thing you need to remember – a class is nothing but an object – yes its a little special, but its an object none the less.

Ruby is even sneakier – when you define a class ‘Foo’, Ruby creates a constant called Foo, and places an object of type Class into it which contains the definition of your klass. Don’t believe me? Run this code –


class Foo
end

puts Foo
puts Foo.class

Which produces


Foo
Class

ie, the contents of a constant, ‘Foo’, (because in Ruby any variable starting with an uppercase letter is a constant) is an instance of Class, called ‘Foo’.

Phew – thats enough for now – next time, I will introduce metaclasses and the other bits and pieces that allow these Rails like ‘has_many’ directives to actually work …

December 13, 2007 at 11:39 pm 1 comment

Four things hotel 1.0 and web app 1.0 have in common

For the past week I have been staying in a very nice hotel, which I just learned opened only a month ago. Today it dawned on me, that opening a new hotel is in many ways a lot like getting version 1.0 of a web application launched.

Hotel 1.0 does not need all the features

Both a hotel and a software product require a large amount of investment to get to the launch date. When developing version 1.0, there is a real temptation to keep adding features that you think are essential, continuously delaying the launch. Guess what – its perfectly fine to get the place opened with only the indoor pool done while the outdoor one is not finished, or when the first restaurant is ready but the second one is not. I can imagine the hotel owner stressing out about all the things he thinks are essential, but to be honest, the guests are not going to care so long as the rough edges are kept out of sight and what is there does its job well.

Just like with software, getting the doors open at the earliest opportunity allows feedback to be gathered from guests, and more importantly start at least a small amount of money coming in!

Hotel 1.0 does not need every to be feature perfect

OK, the rooms need to be perfect as does the food and restaurant – that is what the guests came for (to sleep and probably to eat) – in other words the core features need to be perfect.

However it doesn’t matter that much if the heating doesn’t work in the indoor pool yet, so long as its still usable. Same goes for software – the user experience of the main part of the application had better be spot on, but I can live with some discomfort in the data exporter or preferences pane … for now!

Hotel 1.0 can really impress the early guests

When the hotel opens, it will probably not be booked out on week 1, 2 or even 3. This is a special chance to give exceptional service to the first guests. If the hotel treats the guests really well, responds to any problems quickly and explains the reasons behind the unfinished pool and restaurant they will probably leave happy and evangelise the place to friends and colleagues.

The same goes for new software products. The first customers are the most important – so treat them like kings and they will tell others.

Hotel 1.0 will have many of the best rooms empty

Related to point 3 – when the hotel first opens, many of the more expensive rooms will remain empty. Why not upgrade some guests into these rooms? In doing this, the guests will probably be less annoyed by the unfinished features and they will have a positive story to tell colleagues and friends.

In new web application the same thing goes – bandwidth and servers are not going to be taxed for the first while (unless you hit the Facebook jackpot) so why not give early users the top package for the first few months in the hope they there when the trial period ends?

Honesty is the best Policy

One final important thing – don’t advertise the hotel as having a heated indoor and outdoor pool if only the indoor pool works, and it’s cold – guests will just feel insulted when they find out and that will be what sticks in their mind. Honest usually pays dividends if everything else is good.

If, for any reason you happen to be travelling to Hyderabad on business, version 1.0 of the Ella Compass Suites hotel is highly recommended!

November 18, 2007 at 5:53 pm Leave a comment

Older Posts


Feeds