Blog of Barry

Keeping it Simple

Went on a tough mountain bike ride today. Getting ready for my MTB trip to Tahoe. This trail is called the Big Trees trail. Definitely a good ride with some good climbing and downhill. Plus you get to see some awesome giant redwoods when you get to the top.

Article: Foursquare Checkin Unlocks This Apartment Door, DIY Kits Coming Soon

Foursquare Checkin Unlocks This Apartment Door, DIY Kits Coming Soon
http://www.fastcompany.com/1709781/foursquare-door-guys-say-they-might-start-selling-their-system

Now that truly is the future and along the same lines of some ideas of mine, which I can't wait to implement.

Filed under  //   social networking   technology  

Hillcrest Farms Trip

Oct 9, 2010 12:20:52 PM

At Hillcrest farms for some family fun. They have a train ride, corn
maze, treehouse, and play area. The kids love it and were busy getting
dirty playing with toy construction equipment by the treehouse. Zoya
picked pomegranates and broke them up for us. All in all a nice time.

(download)

Finally Some Time for JacobSix

I finally had a little bit of time this weekend to work on JacobSix.  You can read about the changes at my latest post on the JacobSix blog.

JacobSix is a simple project management tool I created for myself and anyone else who wants to use it.  It's purposely simple and easy to use.  This weekend, I improved the performance of the Action lists a bit as well as cleaned up some of the page refresh.  Check out JacobSix at http://www.jacobsix.com.  Let me know what you think.

Now for the technical talk.  If you aren't technical or do not care about development, no need to continue...

The page refresh was not clean and would show the raw HTML an instant before it displayed the jQuery UI tab control in the project page.  Apparently, it's best to set the DIV element for the tab to "display:hidden" before you render the tabs using jQuery UI.  Once the tab is created, you can then set $('#tab').show().

Performance improvement was a bit trickier.  Google App Engine's ReferenceProperty is very useful.  However, when you use it to get the value of the referenced property value, GAE executes a query for that property.  If you query and get 25 results, then if you refer to the property in each of those 25 results you query the data store 25 times for each property.  Things slow down pretty quick the more ReferenceProperty types you have.  So, to solve it, I need to store the value I want from each of the referenced properties with the parent Model itself.  I then need to update the local copy whenever the actual data changes.  So much for data normalization, but this shows that you need to do what it takes to make things perform.

Fun weekend geocaching

I just discovered Geocaching, and more specifically the site http://www.geocaching.com/, which is "The Official Global GPS Cache Hunt Site." If you don't know what geocaching is, then I encourage you to check out the geocaching.com. However, to save you a little time and put some context behind this post I'll give you a quick idea. It's basically a treasure hunt based on GPS coordinates. Hidden caches are placed all over the globe and the coordinates are all that you have to go by. If you think that's easy, it's not. Some of these little caches are well hidden.

Geocaching.com has all sorts of information, and most importantly a huge database of the hidden cache's you can search through and find some in your area. All you need is a GPS. I used my iPhone and bought their iPhone App. You can search through the database using the app and then click the "Navigate To" button to draw a line from your current location to the cache. Once at the location, you'll need to search around and find the cache. Some are boxes and others are tiny film canisters. Many have things in them that you swap for something else from another cache or your own contribution. You can read the little log included in each one to see who has been there before. Of course, the geocaching site has logs also.

This weekend, my boys and I found Clovis Eagle Cache #6, "T" time, "Quack, Quack, --- Quack, Quack" and Ode to Edison.

Try it and have fun!

Moved the JacobSix Blog

We moved the JacobSix blog to it's own Posterous.  You can now follow it at:

http://jacobsix.posterous.com

All of the updates, news, and more will be posted there from now on.  Enjoy!

New Features in JacobSix

We are working hard to keep making JacobSix a simple, yet powerful Project Collaboration application.  The last sprint has been a very productive one.  Many late nights and lost weekends have added up to some very good progress on JacobSix.

Here are some of the major features additions:

  • Ability to follow a Project - There is a little pin to the right of the project name in the Overview section of the project page.  If this is pinned (pin facing down), you will be following the Project.  What does this mean?  Well, you will get emails when anything changes in the Project, such as new messages, new Milestones or Groups, added Links or Notes.  Pretty much anything at all.  This allows you to keep up to date on any happenings in a Project so you can react quickly.  Eventually, following a Project will lead into IM messages in the future.
  • Ability to follow an Action - The same pin you can put on a Project you can put on an individual Action.  If you don't want to following the entire project, you can just concern yourself with one Action.  When an action is pinned, you wil receive emails if anything about that action changes.
  • Condensed View of Action Lists - You can click the magnifying glass icon above the action list to collapse the action details.  This allows you to fit more on the screen.  You can always expand an individual action to see the details.  The condensed view mode carries across all action lists and your workbook.
  • Displaying Avatar next to Messages - In the Recent Messages list, we now show the avatar of the person who posted the message.
  • Invitations by User Name - You can now search for users that are collaborating with you on other projects to invite them to a new project.
  • Burndown Chart - For those of you who are into Scrum Agile Project Management, then a burndown chart is available.  This chart is based on the Estimated and Actual hours, using the Project Start and Due or Milestone Start or Due dates to build the range.  This chart is in the More Charts page.
  • Commenting on Actions - You can now comment on an Action.  The action assigned and any followers of the action or project will be emailed of any new comments.  This is a good way to communicate and ask questions about an Action.

We have many more enhancements coming soon.  Here is a rundown of what we will be adding soon:

  • Project Feed - The project feed will give you a running stream of all activity in a project.  So, if someone closes an action, it will be in the feed.  If someone adds an action, in the feed.  If a new message is posted, in the feed.  The feed is a temporal view of all things happening in your project.  We will provide an RSS link to this feed so it will be easy to follow day to day the projects progress.
  • Contacts - The ability to store users in a contact list so you can easily invite them to future projects and also communicate with them.
  • User Page - A page dedicated to a user, showing any actions assigned to that user for common projects.

I hope you are finding JacobSix useful and it is helping you with your projects.  If you have any suggestions, feedback, or praise, please let us know at http://getsatisfaction.com/tahelpya/products/tapingya_jacobsix.  We appreciate all suggestions and consider them all seriously.  We want to make JacobSix as useful as we can.

 

Filed under  //   jacobsix  

More features in JacobSix. Rolling through the sprint.

I have spent a large amount of time optimizing the site as much as possible given the GAE limitations and recent slowdown.  What I mean by recent slowdown is the exceedingly long response times that happen.  This is not all the time, but enough to become annoying.  A request that typically takes 300ms to complete is taking 20 seconds in some cases.  Using Google App Engine is both a blessing and a curse.  You get many benefits but also are at the mercy of the Google Infrastructure.  Could be anything between point A and B.  So, I cannot pin the blame entirely on Google.  Maybe something in the network.  Who knows.

Besides performance improvements, I have also added Action Filtering to the "All Actions" page and "All Closed Actions" page.  I'll be creating screencasts soon to demo some of these features and guide people through the site.  It is not a complex application (that was the point), but some of the features are not completely obvious (let me know if this is not the case, I'll be happy to hear this).  From the All Actions page, there is a little arrow button next to the refresh button at the top right of the listing.  Clicking this will expand the filter options.  You can filter by assigned, group, and priority.  This is a combined filter.  So, choosing assigned and priority will filter on both, not either.

Have fun with the feature and let me know other filters you want to see.  I will add due date filtering (between this date and that date).  That one is in the list.

Where is the slowdown in my GAE App?

Click here to download:
profile_helper.py (1 KB)

Recently I noticed JacobSix not performing very well.  Requests would take a long time sometimes, not always.  Well, I think that's the nature of GAE and you cannot expect consistent response times even from the same exact request doing the same amount of work.  Sometimes it takes 300ms, sometimes 3000ms for the same request.  Well, I wanted to make sure it was not something I injected into the code to cause the slowdown so I wanted to time each section of of the request to find out how long it is taking to complete that section.

I created a Profiler class in Python to do just this.  You simply create an instance of the Profiler class.


self.profiler = Profiler(name="Project Controller", enabled=True)

To start profiling a section of code, you call the start() method:


self.profiler.start()

This marks the start time at UTC Now.

To mark a section, you call the mark() method.


self.profiler.mark('BEFORE FETCH')
... some code here
self.profiler.mark('AFTER FETCH')

When you are done timing, you can call the stop() method:

 
self.profiler.stop()
self.profiler.report()

The report() method outputs the results of the timing to logging.info() so you can check it in your logs.  Here is an example output:


======PROFILE REPORT Project Controller======
09-03 05:00PM 12.837 Mark - Name - Between - Accumulatve
09-03 05:00PM 12.837 0 - BEFORE FETCH - 0ms - 0ms
09-03 05:00PM 12.837 1 - AFTER FETCH - 10ms - 10ms
 09-03 05:00PM 12.837 2 - BEFORE JSON - 0ms - 10ms
09-03 05:00PM 12.838 3 - AFTER JSON - 0ms - 10ms
09-03 05:00PM 12.838 4 - BEFORE RENDER - 0ms - 10ms
09-03 05:00PM 12.838 5 - AFTER RENDER - 0ms - 10ms
09-03 05:00PM 12.838 ==============================
 09-03 05:00PM 12.838 TOTAL TIME: 0:00:00.010875 (10ms)
09-03 05:00PM 12.838 ======END PROFILE REPORT======

The report shows you each mark with the description given when you called the mark() method.  Next it shows you the time between each mark section.  The first mark is showing you how long (in ms) it took between the starting time and the mark time.  The next mark shows you how long between mark 0 and 1 and so on.  The accumulative time is just that.  Finally, the total time shows you how long it took between the start() and stop() calls.

There may be better ways out there, but this is what I came up with real fast.  I've attached the source if you want it.  Maybe messy, but I had to put it together quick to test some sections of my code out.  I have some improvements in mind.

GAE definitely forces you to be efficient.  In my case, it turns out that most of the processing was in generating the JSON of the results and very little time was in the FETCH.  However, this is not consistent.  Sometimes, it seems to take GAE much longer to both FETCH and access the memcache.

Another deployment of JacobSix

I'm up again until midnight working on JacobSix.  This will catch up to me soon and I'll definitely crash and burn for a few days.  Going to sleep at midnight and waking at 5:00 AM with the boys is taking its toll.  However, the positive side is that JacobSix is getting better every day.  I worked all night working out bugs with the Invitation workflow.  A major mess, but I think I have it cleaned up.  There were quite a few other issues that I cleaned up tonight.  For example, the "More Charts" was broken if you are filtering on "With Milestones."  Turns out, GAE cannot do "__KEY__" only queries with an inequality filter ( != ).

Another bit of work is to try to increase performance in many of the Datastore queries.  I just don't think it's my issue after looking at the logs and seeing so many inconsistent numbers coming from GAE.  On one request, the processing time is 300ms.  Immediately after, the same exact query comes back as 2000ms.  I don't get it.  I did clean up the indexes, which may help a bit since half of them were not in use.

There's a ton more work to be done to handle errors a bit better.  I'll probably take a step back and clean things up before moving into the next half of this sprint.

If you tried JacobSix and like it, leave me a comment.