Skip to content

Feed aggregator

Software Process and Measurement Cast Five Year Anniversary Press Release

Year Five Press Release (PDF)

For Immediate Release
January 23, 2012

Avon Lake, OH – The Software Process and Measurement Podcast (SPaMCAST) is celebrating its 170th episode after five years of interviewing many of the leaders in the software development world. The anniversary edition of SPaMCAST features an interview with Hillel Glazer, speaker, process guru and author of High Performance Operations.

SPaMCAST feature interviews have included:

  • Chris Hefley, Chief Executive Officer, Leankit Kanban, Bandit Software, LLC
  • Dean Leffingwell author of Scaling Software Agility and others
  • Peter Taylor  author of many books including The Lazy Project Manager
  • Elizabeth Harrin author, award winning blog, The Girl’s Guide to Project Management
  • Tim Lister, co-author of  Adrenaline Junkies and Template Zombies
  • David Anderson the author of  Agile Management for Software Engineering
  • Kent Beck, pioneer in Agile Methods
  • Scott Ambler, though leader in Test Driven Development
  • Ivar Jacobson, developer of Use Cases
  • Grady Booch, discussing Life, the Universe and Development

The Cast covers topics that deal with the challenges of how work is done in information technology organizations as they grow and evolve.  The show combines commentaries, interviews and feedback to serve up ideas, opinions, advice and facts.  In a nutshell, the Cast has provided and will continue to provide advice for and from practitioners, methodologists, pundits and consultants. The editor, Tom Cagley, is a leading consultant in software development process improvement, the Vice President of Consulting for the David Consulting Group, Past President of the International Function Point Users Group and co-author of Mastering Software Project Management.

The Software Process and Measurement Cast can be found at www.spamcast.net. It is also available on all major podcast services including iTunes and the Zune Marketplace. All previous episodes are available download.  The Cast currently enjoys 10,000 downloads a month, up 20% in the past year It is delivered as a free public service to the information technology community and has listeners across the globe.

Contact:
Thomas M. Cagley Jr.
Editor

Email: Spamcastinfo@gmail.com
Mobile: 440.668.5717
Skype ID: Thomas,Cagley.Jr


Categories: Process Management

Episode 182: Domain-Specific Languages with Martin Fowler and Rebecca Parsons

In this episode, Markus talk with Martin Fowler and Rebecca Parsons about domain-specific languages.
Categories: Programming

Rapid Testing Intensive

James Bach’s Blog - Wed, 01/25/2012 - 03:03

Announcing the Rapid Testing Intensive seminar.

This is something new. From July 24 to 28, my brother and I are going to run a short, extreme testing project over five days. We have a nice big space, good Internet, and we’ll be cut off from all distractions.

The most interesting element, from my point of view, is that students can attend onsite OR online. Onsite attendance is more trouble, more work, more expense, but also a completely vivid immersive testing experience where you will work shoulder to shoulder with two of the guys who created the Rapid Testing methodology that is now taught all over the world. Online participants will also test and attend optional webinars twice a day during the week. We will have a dedicated coordinator and an online forum so that the experience will be exactly like working as a remote tester on a busy project team.

The outcome of the week will be a test report that will become a part of each participant’s professional portfolio.

I’m so glad Jon is doing this with me. We complement each other well. Jon is a day-to-day test manager who has applied Rapid Testing in his work for nearly all his career since the mid-90’s. I’m a consultant who’s been teaching Rapid Testing since I invented it. Besides, it gives me an excuse to use this graphic…

This may look like George Lucas and Vladimir Lenin, but it’s me and Jon…

Categories: Testing & QA

Developer machine automation: Dependencies

Mark Needham - Wed, 01/25/2012 - 00:16

As I mentioned in a post last week we’ve been automating the setup of our developer machines with puppet over the last week and one thing that we’ve learnt is that you need to be careful about how you define dependencies.

The aim is to get your scripts to the point where the outcome is reasonably deterministic so that we can have confidence they’re going to work the next we run them.

We noticed two ways in which we haven’t quite achieved determinism yet:

Accidental Dependencies

The first few times that we ran the scripts on top of a vanilla image we were doing it on a virtual machine which had VMware tools installed on it.

We’d forgotten that VMware tools had been installed on those VMs and ran into a problem with Oracle dependencies not being satisfied when we ran puppet on some machines which had CentOS installed directly (i.e. not on a virtual machine).

Those dependencies had been satisfied by our VMware tools installation on the VMs so we didn’t realise that we hadn’t explicitly stated those dependencies, something which we have done now.

External Dependencies

We couldn’t find the Firefox version that we wanted install on the default yum repositories so we created a puppet task which linked to a Firefox RPM on an external server and then installed it.

It worked originally but at some stage over the last couple of weeks the URI was changed as a minor version had been upgraded, breaking our script.

We also came across another way that external dependencies can fail today – if a corporate proxy blocks access to the URL!

We’re trying to get to the stage where we’re only relying on artifacts either coming from a yum repository or an internal repository where we can store any libraries which aren’t available through yum.

Don’t assume determinism

While trying to solve these dependency problems in our puppet scripts I made the mistake of assuming that if the script runs through once and works that it’s always going to be that way in the future.

Since we had achieved that previously in my mind it was impossible for it to fail in future which stopped me from properly investigating why it had stopped working.

Categories: Programming

RVM Stable and More

Engine Yard Blog - Tue, 01/24/2012 - 21:13

Stable RVM has been available for some time now. Many of you may know what goes on in RVM, but there is still a story to tell.

RVM is now using git flow, following the model outlined here, which makes a diametrical change in the release model of RVM. We will no longer make small releases using the master branch. We will have rare larger releases (called latest). Even so, we will maintain a stable branch which gets only fixes and important updates like ruby version updates. This new release model will allow for development of new features in head whilst keeping a stable version of RVM available for production use.

To install stable RVM:

$ bash -s stable < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)

To update stable rvm:

$ rvm get stable # the same as:
$ rvm get branch wayneeseguin/stable

It is also possible to use your own fixes for rvm, which is especially useful for contributors. They can test their work or ask someone else to test their work before sending a pull request. Simply fork the project, add your changes, commit, push and then anyone can install / update to your fork:

$ rvm get branch mpapis/master

RVM now provides information about the age of the installation, in order to see exactly how old the installation is, we can run:

$ rvm info rvm
rvm:
version:      "rvm 1.10.0 by Wayne E. Seguin <wayneeseguin@gmail.com>, Michal Papis <mpapis@gmail.com> [https://rvm.beginrescueend.com/]"
updated:      "2 hours 52 minutes 49 seconds ago"

Significant changes to the output formatting of RVM should be noted—especially the installation and get / notes actions. RVM now displays less information and more readable output when it is installed and updated. The command rvm notes displays all of the important notes that were previously displayed in installation / update process. Updating rvm will now display only the newest updates for notes, so it is not required to run rvm notes after every installation:

$ rvm get head
...
Upgrade Notes:
* If you see the following error message: Unknown alias name: 'default'
re-set your default ruby, this is due to a change in how default works.
...

If we run it again directly afterwards, we will see that there are no new notes:

$ rvm get head
...
Upgrade Notes:
* No new notes to display.
...

Another recent but useful change is the automatic execution of rvm reload after rvm get ...:

$ rvm get head
...
RVM reloaded!
Important Changes

The practice of use-ing rubies from binary has confused a lot of new and experienced users alike. When RVM is loaded as a shell function and calls a binary script instead of a function, the ruby does not become active. This is because external commands or ‘binaries’ cannot affect the environment in which they are called. Currently when rvm is called as a binary (not a function) it will print a warning:

$ command rvm use 1.9.3
RVM is not a function, selecting rubies with 'rvm use ...' will not work.
$ rvm use 1.9.3
Using /home/mpapis/.rvm/gems/ruby-1.9.3-p0

It was often useful in scripts to call the binary with the --default switch to make a given ruby the default. The new way to accomplish this is to explicitly create the default alias (which is what was done in background for the --default flag):

$ rvm alias create default <version>

RVM will no longer install a new ruby if it is already present:

$ rvm install 1.9.3

To make a clean re-install we must now use the reinstall action:

$ rvm reinstall 1.9.3

The old behavior of installation directly over top (not cleaning the sources beforehand) is still available with the --force flag:

$ rvm install 1.9.3 --force

As there were a lot of fixes in rvm, some changes require updating your system files. To update these files, use the --auto switch. This is very handy, especially for multi-user installations—also called ‘root’ or ‘system’ installations—as it will update the files in /etc to provide the latest settings from RVM:

$ rvm get head --auto

Another important change is added third installation type for rvm - mixed mode, now every user can decide to use his private rubies/gemsets:

$ rvm user [gemsets/all]

On Linux, it is also now possible for sysadmins to define rvm configuration by default for all new users that will be created with the --skel flag (which updates /etc/skel):

$ sudo rvm user [gemsets/all] --skel
The goal of RVM has always been to make the job of managing different ruby versions easier. To further this cause, we have implemented a few new installation switches:For setting default mode on JRuby / Rubinius there are --18 and --19flags:

$ rvm install rbx --19   # will install Rubunius with default mode set to 1.9
$ rvm install jruby --18 # will install JRuby with default mode set to 1.8

For compiling 32 bit mode ruby on OS X we have --32, --64 and --universal flags:

$ rvm install 1.9.3 --universal # to build fat binary including both 32 and 64 bit binaries
$ rvm install 1.8.7 --32 # to build only 32 bit ruby
$ rvm install 1.8.7 --with-arch=i386 # is equivalent to the 32 bit one, but is available only via RVM, ruby 1.8.7 sources do not support it.

For named rubies there is additional validation to help avoid naming issues; only valid names will be allowed for installation:

$ rvm install 1.8.7 --32 -n 32 # will fail
$ rvm install 1.8.7 --32 -n n32 # will work
$ rvm install 1.8.7-n32 --32 # equivalent of the above

Last but not least, RVM has reworked display-color management. RVM by default will now show colored outputs on the console and disables colors when there is no terminal attached. Colors can be also disabled with an environment variable or command line switch:

$ rvm list         # will show the colored list by default in terminal
$ rvm --color=force list | less -R         # will show the colored list in less
$ rvm_pretty_print_flag=auto rvm list | tee my-rubies.list         # will automatically disable colors
$ rvm --color=no list         # will always disable colors

But wait! There’s More! Act now and you OS X users can have a shiny new tool! The official RVM GUI JewelryBox, version 1.2, has been released! It now supports all of the RVM changes we have mentioned above!

Categories: Programming

You're Not a Complexity Thinker When...

NOOP.NL - Jurgen Appelo - Tue, 01/24/2012 - 18:40

You’re not a complexity thinker when… you claim your interpretation of complexity is correct, while others’ are wrong. Because, among scientists, there is no consensus about complexity.

You’re not a complexity thinker when… you predict someone else’s approach to generating change will be wrong, because complexity theory denies predictions based on earlier events.

You’re not a complexity thinker when… you complain your model is misunderstood or misrepresented by many people because the point of your model should be to enable sense-making.

You’re not a complexity thinker when… you only promote your own model, and always attack other people’s models. Because complexity science is against one-size-fits-all.

You’re not a complexity thinker when… you avoid working with people who disagree with you. Because complexity absorption entails creating options and risk-hedging strategies.

You’re not a complexity thinker when… you take your own thinking too seriously.

Categories: Project Management

The State of NoSQL in 2012

This is a guest post by Siddharth Anand, a senior member of LinkedIn's Distributed Data Systems team. 

Preamble Ramble

If you’ve been working in the online (e.g. internet) space over the past 3 years, you are no stranger to terms like “the cloud” and “NoSQL”.

In 2007, Amazon published a paper on Dynamo. The paper detailed how Dynamo, employing a collection of techniques to solve several problems in fault-tolerance, provided a resilient solution to the on-line shopping cart problem. A few years go by while engineers at AWS toil in relative obscurity at standing up their public cloud.

It’s December 2008 and I am a member of Netflix’s Software Infrastructure team. We’ve just been told that there is something called the “CAP theorem” and because of it, we are to abandon our datacenter in hopes of leveraging Cloud Computing.

Huh?

Categories: Architecture

An ode to running a database on bare metal

Agile Testing - Grig Gheorghiu - Tue, 01/24/2012 - 18:03

No, my muse is not quite as strong as to inspire me to write an ode, but I still want to emphasize a few points about the goodness of running a database on bare metal.

At Evite, we use sharded MySQL for our production database. We designed the current architecture in 2009, when NoSQL was still very much in its infancy, so MySQL seemed a solid choice, a technology that we could at least understand. As I explained elsewhere, we do use MySQL in an almost non-relational way, and we sharded from the get-go, with the idea that it's better to scale horizontally than vertically.

We initially launched with the database hosted at a data center on a few Dell PE2970 servers, each with 16 GB of RAM and 2 quad-core CPUs. Each server was running 2 MySQL instances. We didn't get a chance to dark launch, but the initial load testing we did showed that we should be OK. However, there is nothing like production traffic to really stress test your infrastructure, and we soon realized that we have an insufficient number of servers for the peak traffic we were expecting towards the end of the year.

We decided to scale horizontally in EC2, with one MySQL instance per m1.xlarge EC2 instance. At the time we also engaged Percona and they helped us fine-tune our Percona XtraDB MySQL configuration so we could get the most out of the m1.xlarge horsepower. We managed to scale sufficiently enough for our high season in 2010, although we had plenty of pain points. We chose to use EBS volumes for our database files, because at the time EBS still gave people the illusion of stability and durability. We were very soon confronted with severe performance issues, manifested as very high CPU I/O wait times, which were sometimes so high as to make the instance useless.

I described in a previous post how proficient we became at failing over from a master that went AWOL to a slave. Our issues with EBS volumes were compounded by the fact that our database access pattern is very write-intensive, and a shared medium such as EBS was far from ideal. Our devops team was constantly on the alert, and it seemed like we were always rebuilding instances and recovering from EC2 instance failures, although the end-user experience was not affected.

Long story short, we decided to bring the database back in-house, at the data center, on 'real' bare-metal servers. No virtualization, thanks. The whole process went relatively smoothly. One important point I want to make here is that we already had a year's worth of hard numbers at that point regarding the access patterns to our database, iops/sec, MySQL query types, etc, etc. So it made it easy to do proper capacity planning this time, in the presence of production traffic.

We started by buying 2 Dell C2100 servers, monster machines, with dual Intel Xeon X5650 processors (for a total of 24 cores), 144 GB RAM, and 12 x 1 TB hard disks out of which we prepared a 6 TB RAID 10 volume which we further divided in LVM logical volumes for specific types of MySQL files.

We put 2 MySQL instances on each server, and we engaged Percona again to help us fine-tune the configuration, this time including not only MySQL, but also the hardware and the OS. They were super helpful to us, as usual. Here are only some of the things they recommended, which we implemented:
  • set vm.swappiness kernel setting to 0 in /etc/sysctl.conf
  • set InnoDB flush method to O_DIRECT because we can rely on the RAID controller to do the caching (we also mounted XFS with the nobarrier option in conjunction with this change)
  • disable MySQL query cache, which uses a global mutex that can cause performance issues when used on a multi-core server
  • various other optimizations which were dependent on our setup, things like tweaking MySQL configuration options such as key_buffer_size and innodb_io_capacity
One important MySQL configuration option that we had to tweak was innodb_buffer_pool_size. If we set it too high, the server could start swapping. If we set it too low, the disk I/O on the server could become too problematic. Since we had 144 GB of RAM and we were running 2 MySQL instances per server, we decided to give each instance 60 GB of RAM. This proved to strike a good balance.
Once the fine-tuning was done, we directed production traffic away from 4 EC2 m1.xlarge instances to 2 x 2 MySQL instances, with each pair running on a C2100. We then sat back and wallowed for a while in the goodness of the I/O numbers we were observing. Basically, the servers were barely working. This is how life should be. 
We soon migrated all of our MySQL masters back into the data center. We left the slaves running in EC2 (still one m1.xlarge slave per MySQL master instance), but we changed them from being EBS-backed to using the local ephemeral disk in RAID 0 with LVM. We look at EC2 in this case as a secondary data center, used only in emergency situations.
One thing that bit us in our bare-metal setup was....a bare-metal issue around the LSI MegaRAID controllers. I already blogged about the problems we had with the battery relearning cycle, and with decreased performance in the presence of bad drives. But these things were easy to fix (again thanks to our friends at Percona for diagnosing these issues correctly in the first place...)
I am happy to report that we went through our high season for 2011 without a glitch in this setup. Our devops team slept much better at night too! One nice thing about having EC2 as a 'secondary data center' is that if need be, we can scale out horizontally   by launching more EC2 instances. In fact, we doubled the number of MySQL slave instances for the duration of our high season, with the thought that if we need to, we can double the number of shards at the application layer, and thus scale horizontally that way. We didn't have to do any tweaking fortunately, but we were able to -- a strategy which would otherwise be hard to pull off if we didn't have any cloud presence, unless we bought a lot of extra capacity at the data center.
This brings me to one of the points I want to make in this post: it is a very valuable strategy to be able to use the cloud to roll out a new architecture (which you designed from the get-go however to be horizontally scalable) and to gauge its performance in the presence of real production traffic. You will get less than optimal performance per instance (because of virtualization vs. real hardware) , but since you can scale horizontally, you should be able to sustain the desired level of traffic for your application. You will get hard numbers that will help you do capacity planning and you will be able to bring the database infrastructure back to real hardware if you so wish, like we did. Note that Zynga has a similar strategy -- they roll out new games in EC2 and once they get a handle on how much traffic a game has, they bring it back into the data center (although it looks like they still use a private cloud and not bare metal).
Another point I want to make is that the cloud is not ready yet for write-intensive transactional databases, mainly because of the very poor I/O performance that you get on virtual instances in the cloud (compounded by shared network storage such as EBS). Adrian Cockcroft will reply that Netflix is doing just fine and they're exclusively in EC2. I hope they are doing just fine, and I hope his devops team is getting some good sleep at night, but I'm not sure. I need to perhaps qualify my point and say that the cloud is not ready for traditional transactional databases such as MySQL and PostgreSQL, which require manual sharding to be horizontally scalable. If I had to look at redesigning our database architecture today, I'd definitely try out HBase, Riak and maybe Cassandra. The promise there at least is that adding a new node to the cluster in these technologies is much less painful than in the manual sharding and scaling scenario. This still doesn't guarantee that you won't end up paying for a lot of instances to compensate for poor individual I/O per instance. Maybe a cloud vendor like Joyent with their SmartMachines will make a difference in this area (in fact, it is on our TODO list to test out their Percona SmartMachine).
Note however that there's something to be said about using good ol' RDBMS technologies. Ryan Mack says this in a Facebook Engineering post:
"After a few discussions we decided to build on four of our core technologies: MySQL/InnoDB for storage and replication, Multifeed (the technology that powers News Feed) for ranking, Thrift for communications, and memcached for caching. We chose well-understood technologies so we could better predict capacity needs and rely on our existing monitoring and operational tool kits."

The emphasis on the last sentence is mine. It's the operational aspect of a new architecture that will kill you first. With a well understood architecture, at least you have a chance to tame it.
Yet another point I'd like to make is: do not base your disaster recovery strategy in EC2 around EBS volumes, especially if you have a write-intensive database. It's not worth the performance loss, and most of all it's not worth the severe and unpredictable fluctuation in performance. It works much better in our experience to turn the ephemeral disks of an m1.xlarge EC2 instance into a RAID 0 array and put LVM on top of that, and use it for storing the various MySQL file types. We are then able to do LVM snapshots of that volume, and upload the snapshots to S3. To build a new slave, we can restore the snapshot from S3, then catch up the replication with the master. Works fine.
There you have it. An ode in prose to running your database on bare metal. Try it, you may sleep better at night!

Agile Lifecycles for Geographically Distributed Teams, Part 1

I’ve been working with geographically distributed and dispersed teams for the past couple of years. Some of them on quite large programs, some of them reasonably small. What they all have in common is that they all want to transition to agile.

Most of them start this way: someone takes a Scrum class, gets all excited. This is good. Then reality hits. Scrum is meant for collocated geographically cross-functional teams. Uh oh.

Almost all of these teams are separated by function: the developers are in one place, the testers are in another, the business analysts are in a third place, the project managers are in a fourth places, and if there are product owners (or what passes for product owners) they are often in a fifth location. It’s not uncommon for every single function of the team to be separate from every other member of the team. So, the teams don’t fit the Scrum criteria. Uh oh.

Since Scrum has so much brand recognition, these people think if they can’t do Scrum, they can’t do Agile. Nope, not so. What they need to do is start from the values and principles of the Agile Manifesto, and go from there. They create their own lifecycle, and their very own brand of Agile.

When I worked with one client, that client thought they could extend their iteration. Nope, if anything, that means you keep the iterations even shorter, because you need more frequent feedback when no one is in the same place. Well, there were words. And more words. But, if you start from the values, you see that short iterations are the way to go if you want to be agile. Otherwise, you get staged delivery, which is a lovely lifecycle, but not agile.

I’m blogging a series of examples. Please don’t ask me why the people ended up in these locations. I have no idea. All I know is that’s where the people are.

Example 1: Using a Project Manager With Iterations, Silo’d Teams

One IT organization has teams with developers in the Ukraine, testers in India, product managers and project managers in the UK, and enterprise architecture and corporate management in the eastern US.

This organization moved to two-week iterations. The developers were 3.5 hours ahead of the testers, which was not terrible. This organization had these problems:

  1. The product managers had to learn to be product owners and write stories that were small enough to finish inside one iteration.
  2. The enterprise architects had to stop dictating the architecture without features to hang off the architecture.
  3. The developers and testers had to learn to implement by feature so the architects could help the team see the evolving architecture.

This organization had a ton of command-and-control to start. The project managers needed to facilitate the teams, not control them. The architects needed to help the teams see how to organize the product, not to tell the developers what to do. The testers needed to not be order-takers, as in taking orders from the developers.

You might ask why the organization wanted to move to agile. Senior management wanted agile because the releases got longer and longer and longer, and could not accommodate change. Agile was a complete cultural shift. The two-week iterations, along with an agile roadmap of features helped a lot.

The pilot project team consisted of the developers, testers, a product manager, and a project manager. The team rejected the enterprise architect as a member of the team because the architect refused to write code.

Release planning: The project manager and the product manager do an initial cut at release planning as a strawman and presented it to the team. “Can you do this? What do you think?”

Iteration planning: The team does iteration planning together, making sure every story is either small, medium, or large, where a large story can be done by the entire team in fewer than three days. The team makes sure they get every started story to done at the end of the iteration.

Daily commitment: The team does a daily checkin, not a standup. They timebox the checkin to 15 minutes. They ask these questions:

  • What did you complete and with whom yesterday? (reinforces the idea that people work together)
  • What are you working on and with whom today?
  • What are your impediments?

The project manager who acts as a servant leader, not a command/controller manages the impediments.

The pilot project has two experienced agile people: the project manager and a developer. Both act as servant leaders.

Measurements: burnup charts, impediment charts

The pilot team has been together for six months now, and is successful. This is not Scrum. It’s not Kanban. It’s agile and it’s working. They are ready to start another project team, working by attraction.

(Want to learn to work more effectively on your geographically distributed team? Join Shane Hastie and me in a workshop April 17-18, 2012.)

Categories: Project Management

Stop Storing Passwords Already!

This is largely common sense already, but I still frequently run into people who don't know how dangerous this is or how to properly store user credentials. The many Anonymous hacks in the past year that resulted in the leaking of users' passwords also show that many sites still store passwords in either clear-text or encrypted form. It's actually quite simple to store credentials safely, so here's a quick recap and example.

The biggest issue with storing passwords is that you have to assume that it's always possible that someone can get access to your database. Yes, even if it's not directly exposed to the outside world, which it never should be. Whatever security measures you've put in place to protect your database, it's a good idea to assume that sooner or later, someone will be able to punch a hole through your security measures and be able to read the data. So obviously, you really don't want to store clear-text passwords. You also don't want to store encrypted passwords because encrypted data can always be decrypted. And if people get access to those encrypted passwords even if they weren't supposed to, it'd be wise to assume that they also know how to decrypt them, or that it won't take them long to figure it out.

A much better approach is to store a hashed representation of the password instead, using a strong one-way cryptographic algorithm and a unique salt value per password. If the cryptographic algorithm is one-way, it means you can't apply another algorithm to get the original source value again. The only way to compare passwords is to apply the cryptographic algorithm on a given password using the originally used salt value, and then compare the resulting hash with the one you've stored. If they are identical, the given password is the same as the one that was used originally. If they differ, the password is invalid.

Attackers can still employ rainbow tables to try to find password values that generate the same hashes as the ones in your database. Luckily, generating rainbow tables takes time and plenty of space as well so it makes it much harder for attackers to find the passwords. This is why it's so important to use a unique salt value per password. It effectively means that a rainbow table would have to be generated for every single salt value that you've used, making it practically infeasible to find the original password values.

Let's demonstrate this with a simple example. The example is from a Node.js application, but this technique can be applied with whatever technology stack you're using.

This is my User model:

var mongoose = require('mongoose'),
    crypto = require('crypto'),
    uuid = require('node-uuid'),
    Schema = mongoose.Schema,
    ObjectId = Schema.ObjectId;

var userSchema = new Schema({
    name: { type: String, required: true, unique: true },
    email: { type: String, required: true },
    salt: { type: String, required: true, default: uuid.v1 },
    passwdHash: { type: String, required: true }
});

var hash = function(passwd, salt) {
    return crypto.createHmac('sha256', salt).update(passwd).digest('hex');
};

userSchema.methods.setPassword = function(passwordString) {
    this.passwdHash = hash(passwordString, this.salt);
};

userSchema.methods.isValidPassword = function(passwordString) {
    return this.passwdHash === hash(passwordString, this.salt);
};

mongoose.model('User', userSchema);
module.exports = mongoose.model('User');

Notice that the salt property of my User type has its default value set to 'uuid.v1'. In this case, uuid.v1 is a function which will be invoked by Mongoose whenever a new User instance is created. Every User instance will thus have a UUID value stored in its salt property. You can also see that I'm not storing the given passwordString in the setPassword function, but that I calculate the hash value based on the passwordString and the UUID salt value.

Suppose I create a user with the following code:

var user = new User({
    name: 'test_user',
    email: 'blah'
});
user.setPassword('test');

user.save(function(err, result) {
    if (err) throw err;
}); 

Its database representation will look like this:

{ 
    "passwdHash" : "b604367796274cf64177eec345532fc6ca66c6f0501906f82bb03f7916265e9d", 
    "name" : "test_user", 
    "email" : "blah", 
    "_id" : ObjectId("4f1dbb2cfa6157b118000001"), 
    "salt" : "304a33f0-45fc-11e1-80d2-43c594a44fa0" 
}

If an attacker would get access to this, he'd have to generate a rainbow table using the salt value, which takes time, and even then he has no guarantee that the rainbow table will actually contain the correct password. Again, this is why it's so important to use a unique salt for every password. Also, you can use whatever value you want as the salt value so if you can determine it based on some other fields or by using a specific formula you don't need to store the actual salt value. It's recommended to use a long salt value though. Theoretically speaking, it's safer if the salt value isn't stored so clearly as I'm doing here, but even with the salt value clearly visible to a possible attacker, it would still be practically infeasible for him to generate all those rainbow tables.

And of course, my actual authentication function is still very simple as well:

var authenticate = function(username, password, callback) {
    User.findOne({ name: username }, function(err, user) {
        if (err) return callback(new Error('User not found'));
        if (user.isValidPassword(password)) return callback(null, user);
        return callback(new Error('Invalid password'));
    });
};

So as you can see, there's nothing hard or complicated about storing credentials in a secure manner. It's quite easy to do so and there are no downsides to doing this.

Categories: Programming

Installing a nodejs application without your good old internet

Xebia Blog - Mon, 01/23/2012 - 19:55

While we were building a little server to enable auditlogging on our hadoop cluster (more on that in a future blogpost) we needed a way to distribute our application.
This blog is about the packaging of this application. The application is build with nodejs and packaging and dependency management is mostly done with npm (the node package manager).

Of course installing this application in the production environment should have been as easy as the setup on our own laptop’s right? Wrong! On our laptops it was a easy git clone followed by a npm install and voila we have a running application. So how hard could it be to do this on a server at the client. Let me tell you….

This server is not connected to the internet, so the git clone wouldn’t work in the first place. Not really a problem because it’s a small app and we could just make a tarball and ship it to the server.
Next thing was all our dependencies. We used a few modules which were mentioned as dependencies in our package.json file so npm with the install command would do it’s magic.

The npm install magic consists, among other things, of getting the modules from the npm registry and that fails if you’re not connected to the internet. Searching for a way to do this differently I figured out that npm had a cache directory and thought I could get the stuff from there. This might have worked, but with that solution I would miss the dependencies where these modules depended on. And it would be a messy kind of script that I needed to make.

Browsing the internet didn’t provide me with the right answer but it led me on the path to the npm pack function. This is used to pack your module together with all dependencies. The only thing you need to configure it correctly, is a separate array containing the dependencies to bundle with your app.

So far so good, so I went on and added a bundleDependencies section in my package.json and ran npm pack.
The result was a nice .tgz file containing all the files needed for the application together with all the modules it depended on. At least the main modules it depended on. My fellow programmers in crime from which I got these modules hadn’t bothered to add this extra section, so npm had no notice of the modules they depended on.

This was easy to solve. Just add a correct section of bundleDependencies to all package.json files.
Sounded like a boring task to do this manually and because I love my programming job, I decided to write a program for it.

My obvious choice of programming languages was: awk, grep and sed. Why? Because I can.
Without further ado, here it is:

    awk '/dependencies/,/]|}/' $file |
    grep -o '\".*\".*:' |
    sed 's/^.*{//g' |
    sed 's/\"dependencies.*\://g' |
    grep -v -e '^$' |
    uniq |
    sed 's/\"[ ^I]\:/\",/g' |
    sed 's/\"\:/\",/g' |
    sed '$ s/,/ ]/' |
    sed '1 s/\"/\"bundleDependencies\" \: [ \"/' |
    sed 's/\"/\\"/g' |
    tr -d '\n'

What it does, you ask?
I'll explain line by line:

line1: get the dependencies part (an array or json object) from the file (the package.json file)
ex: "dependencies" : { "express": "0.2.2", "findit" : "0.0.1" }

line2: get only the stuff from that object between the double quotes before the colon (removing the version number part of the dependency)
ex: "express":
"findit":

line3: remove anything preceding the {
line4: remove the original dependencies text
line5: remove any empty lines
line6: remove duplicates

line7 and line8: replace the ": by ", so we can create an array from it
ex: "express",
"findit",

line9: replace the last , by an ] to close the array
ex: "express",
"findit"]

line10: replace the first " by "bundleDependencies" : [ "
ex: "bundleDependencies" : [ "express",
"findit"]

line11: precede all quotes by a backslash so it can be safely used in the sed command to add it to the file

line12: remove all newlines
ex: "bundleDependencies" : [ "express", "findit"]

This is added to the package.json file we are currently processing and if we have finished doing this for all package.json files we can use npm pack to create our tarball.
Works pretty well I might say. But I'm the first to admit this isn't the most readable program ever written.

Of course when building a node application you might have node around to help you do this so I also created a javascript version to do this:

var fs=require('fs')
var findit=require('findit')

findit.find('.', function(name) {
  if (endsWith(name,'package.json')) {
    handleFile(name)
  }
}).on('end', bundleApp)

function handleFile(file) {
  var data = fs.readFile(file, function(err, data) {
    if (err) {
      console.log('Not processesed '+file+' bo the following error: '+err)
    } else {
      var arr = []
      var packageFile = JSON.parse(data)
      if (packageFile.bundleDependencies) {
        console.log('Bundledeps already present. Skipping')
      } else {
        for (var d in packageFile.dependencies) {
          arr.push(d+"")
        }
        if (arr.length > 0) {
          packageFile['bundleDependencies'] = arr
          fs.writeFile(file, JSON.stringify(packageFile, null, 4))
        }
      }
    }
  })
}

function bundleApp() {
  console.log('Finished. preparing package.json files for packaging. Now run npm pack to create the fullblown tarball')
  //exercise left for the reader to require('npm') and run the pack command
}

function endsWith(str, suffix) {
  return str.indexOf(suffix, str.length - suffix.length) !== -1;
}

Hope somebody can benefit from this in the future.

Share

Let's make TCP faster

Google Code Blog - Mon, 01/23/2012 - 19:02
Author Photo
By Yuchung Cheng, Make The Web Faster Team

Transmission Control Protocol (TCP), the workhorse of the Internet, is designed to deliver all the Web’s content and operate over a huge range of network types. To deliver content effectively, Web browsers typically open several dozen parallel TCP connections ahead of making actual requests. This strategy overcomes inherent TCP limitations but results in high latency in many situations and is not scalable.

Our research shows that the key to reducing latency is saving round trips. We’re experimenting with several improvements to TCP. Here’s a summary of some of our recommendations to make TCP faster:

1. Increase TCP initial congestion window to 10 (IW10). The amount of data sent at the beginning of a TCP connection is currently 3 packets, implying 3 round trips (RTT) to deliver a tiny 15KB-sized content. Our experiments indicate that IW10 reduces the network latency of Web transfers by over 10%.

2. Reduce the initial timeout from 3 seconds to 1 second. An RTT of 3 seconds was appropriate a couple of decades ago, but today’s Internet requires a much smaller timeout. Our rationale for this change is well documented here.

3. Use TCP Fast Open (TFO). For 33% of all HTTP requests, the browser needs to first spend one RTT to establish a TCP connection with the remote peer. Most HTTP responses fit in the initial TCP congestion window of 10 packets, doubling response time. TFO removes this overhead by including the HTTP request in the initial TCP SYN packet. We’ve demonstrated TFO reducing Page Load time by 10% on average, and over 40% in many situations. Our research paper and internet-draft address concerns such as dropped packets and DOS attacks when using TFO.

4. Use Proportional Rate Reduction for TCP (PRR). Packet losses indicate the network is in disorder or is congested. PRR, a new loss recovery algorithm, retransmits smoothly to recover losses during network congestion. The algorithm is faster than the current mechanism by adjusting the transmission rate according to the degree of losses. PRR is now part of the Linux kernel and is in the process of becoming part of the TCP standard.

In addition, we are developing algorithms to recover faster on noisy mobile networks, as well as a guaranteed 2-RTT delivery during startup. All our work on TCP is open-source and publicly available. We disseminate our innovations through the Linux kernel, IETF standards proposals, and research publications. Our goal is to partner with industry and academia to improve TCP for the whole Internet. Please watch this blog and http://code.google.com/speed/ for further information.


Yuchung Cheng works on the transport layer to make the Web faster. He believes the current transport layer badly needs an overhaul to catch up with other (networking) technologies. He can be reached at ycheng@google.com.

Posted by Scott Knaster, Editor
Categories: Programming

Facebook Timeline: Brought to You by the Power of Denormalization

Facebook Timeline is audacious in scope. It wants to compile a complete scrollable version of your life story from photos, locations, videos, status updates, and everything you do. That could be many decades of data (hopefully) that must stored and made quickly available at any point in time. A huge technical challenge, even for Facebook, which we know are experts in handing big data. And they built it all in 6 months.

Facebook's Ryan Mack shares quite a bit of Timeline's own implementation story in his excellent article: Building Timeline: Scaling up to hold your life story

Five big takeaways from the article are:

Categories: Architecture

Mobile Test Automation the SOASTA way with TouchTest

Fred Beringer - Mon, 01/23/2012 - 16:20

Kinect Minority Report UI 2 Mobile Test Automation the SOASTA way with TouchTest

2 weeks ago I’ve spent a week at SOASTA HQ for our 2012 kick-off. A good opportunity to meet old friends, and make new ones! As you know, in December we’ve raised an additional $12M to expand our business and awesome people are joining the revolution every day! On the menu was a recap of 2011, plan and objectives for 2012 and of course a little bit of partying and dancing (first ankle tear for me in 2012! But I think I’ve scored some major points on the dance floor icon smile Mobile Test Automation the SOASTA way with TouchTest )

But during this week there was a true seminal moment, not only for me but for the whole team at SOASTA.

The engineering team led by Tal Broda  unveiled what they had been working on for the last 2 months, day and night. I knew they were working on something yet again very disruptive but the secret was well kept and I couldn’t wait to see it for my own eyes. Imagine the scene: On the stage, a combination of ipad and iphone (iPad 1 and 2, iPhone 3G, 4 and 4S). The lead developer for this project (Tana Jackson, 23 Ironman under her belt!) had an ipad in her hand, untethered. She launched a demo application with colorful cubes displayed on the screen and started playing with them: Moving them, making circles, making them bigger, smaller … All the typical gestures you can expect from an iOS app. And in CloudTest, the magic happened: All these gestures were recorded in real-time in a typical CloudTest clip. But best of all, all the recorded gestures could be then replayed perfectly on the 5 iOS devices sitting on the stage. MIND BLOWING!

How in hell was that working? If you’re familiar with mobile test automation, you know that the market is today split into 2 types of products: Those relying on simulator and emulator and those on optical recognition. Both approaches are far from perfect: With simulator, you’re very far from reproducing the true user experience as it should occur on a real device. And with optical recognition, you have not only to invest a good part of your budget to afford it but the maintenance of test cases is a nightmare as you’re working at the pixel level … 4 pixels off and your test is broken. Most of the customers we’ve talked to are facing the same challenges when it comes to mobile test automation: They’ve tried a lot of open-source and commercial products before going back to … manual testing.

So just like in 2008 when Tom Lounibos, SOASTA CEO, addressed the challenges of load and performance testing to allow company to test at scale their web application, today SOASTA wipe away the challenges of test automation for native mobile apps. No more simulator or emulator, no more crazy expensive optical recognition mechanism. Nope, you’re going to be able today to test INSIDE THE APP. Record events from the app as they occur on the device. All possible gestures: Tap, doubleTap, swipe, scroll, pinchOpen, pinchClosed, etc. You will record their speed, velocity and acceleration and replay them on your mobile devices. And since the new mobile capabilities are part of the CloudTest platform, you take advantage of everything you’ve been using when executing load testing or functional test for web application ie. All the visual programming language, creating transaction, validating every steps of your test cases etc. If you’re familiar with CloudTest, then you’re all set to test mobile apps!

This is a short demo I’ve recorded so you can get a better feel of what CloudTest is:

This is what we’re announcing today:

  • TouchTest technology – this is the core of the announcement.  TouchTest is our unique capability to record and replay ALL mobile gestures with full precision from inside iOS and Android mobile applications without tethering to or jailbreaking real mobile devices for functional and performance testing of mobile apps (Windows & others to come). There is nothing like this – all other approaches are incomplete, brittle, and unstable due to their external OCR and physically hardwired approaches. As we operate inside the app, we support native mobile, mobile web and hybrid mobile apps.
  • Private Device Clouds – because there is no need to tie down or physically or electronically “break” into a device, any employee or developer’s mobile device, anywhere, can be used as part of a private device cloud used for automated functional tests during development or as user experience devices for performance testing.  Our customers with 5 or 500 developers all over the world can now be part of a private mobile test cloud when and as needed.  Our platform connects and manages all the devices.
  • iOS and Android labs – we’re packaging our offering for mobile functional testing into labs targeting mobile development shops and orgs focusing on iOS and Android app development (more mobile labs will follow)

2008 marked a giant leap for load and performance testing when SOASTA first introduced CloudTest. 2012 is as big of a leap applied to mobile test automation. I feel so honored to be part of this adventure … I feel like the guys working at Apple in 1983 on the Macintosh … We’re trying to make a dent in the software testing universe and it looks like we’re making a BIG one!

We have a webinar coming up on Thursday dedicated to TouchTest. DON’T MISS IT! You’ll get more explanation on how the whole technology works.

To wrap up this post, this is what Tom tweeted last week. This is what the SOASTA team is all about … Kudos to all who makes it happen!

the crazyones Mobile Test Automation the SOASTA way with TouchTest

Get Shareaholic

Related posts:

  1. The Cloud: A game changer to test, at scale and in production, SOA based web and mobile applications.
  2. Getting started in mobile web performance
  3. Let’s meet Tuesday at the French Testing Day (Journée Française du Test Logiciel)
  4. Early Christmas – SOASTA secures another $12M in funding!
  5. SOASTA is hiring the BEST performance engineers in Europe

Categories: Testing & QA

SPaMCAST 170 - Hillel Glazer, High Performance Operations, CMMI, Agile

Software Process and Measurement Cast - Mon, 01/23/2012 - 00:55

Welcome to the Software Process and Measurement Cast 170! Happy fifth anniversary from Amsterdam!

The SPaMCAST 170 features my interview Hillel Glazer.  We discussed his book High%20Performance%20Operations:%20Leverage%20Compliance%20to%20Lower%20Costs,%20Increase%20Profits,%20and%20Gain%20Competitive%20Advantage%20(FT%20Press%20Operations%20Management)%20">High Performance Operations: Leverage Compliance to Lower Costs, Increase Profits, and Gain Competitive Advantage and many other topics like the CMMI and Agile.

Hillel Glazer is recognized as the world’s leading authority on introducing lean and agile concepts into the compliance-driven world.  He’s helped companies of all sizes and industries around the world successfully streamline their operations, increase value, and expose and eliminate practices that prevent them from achieving their performance goals.  And, he does so while simultaneously accounting for all the external compliance pressures on their operations.

Hillel’s professional passion is to work with companies motivated to achieve world-class operations and excellence.  His diverse experience base includes aerospace/defense and systems engineering, large and small consulting practices, Federal agencies, dot-com operations and financial, insurance, medical and transportation systems development and support.  Having started in manufacturing where he learned the fundamentals of lean production, for more than the most recent decade, as a consultant, Hillel’s been successfully pioneering the introduction of lean philosophies, methods and techniques into businesses and industries otherwise believed to be either too chaotic or too highly restricted in freedom by their compliance and regulation requirements to be able to adopt high performance approaches.

Hillel is an in-demand speaker, presenter, and facilitator.  (See where he’ll show up next.)  He is widely read, broadly published, and appears worldwide on the topics pertaining to operational excellence in compliance-driven industries. His work appears in many publications including periodicals and the texts, CMMI for Services, 2nd Edition, CMMI for Development, 3rd Edition, and Integrating CMMI and Agile Development.

His Baltimore-based company, Entinex, has a global reach that focuses on generating powerful results for high performance operations among companies motivated to be lean, agile, and achieve world-class levels of operational excellence.  He lives in the Baltimore suburbs with his fabulous wife and four amazing children.

If you are going to buy Hillel's book and want to support the SPaMCAST please use the following link which uses the SPaMCAST's Amazon Associate account.  High%20Performance%20Operations:%20Leverage%20Compliance%20to%20Lower%20Costs,%20Increase%20Profits,%20and%20Gain%20Competitive%20Advantage%20(FT%20Press%20Operations%20Management)%20">Buy the book!

Contact Data:
Web:  http://hillelglazer.com
Web:  http://www.entinex.com/
Linkedin: http://www.linkedin.com/in/hillelglazer
Twitter: http://twitter.com/hi11e1
Facebook: http://www.facebook.com/pages/Entinex-Inc/263402040088?ref=ts 

Shameless Ad for my book! 

Mastering%20Software%20Project%20Management:%20Best%20Practices,%20Tools%20and%20Techniques%20">Mastering Software Project Management: Best Practices, Tools and Techniques co-authored by Murali Chematuri and myself and published by J. Ross Publishing. We have received unsolicited reviews like the following: "This book will prove that software projects should not be a tedious process, neither for you or your team."  Mastering%20Software%20Project%20Management:%20Best%20Practices,%20Tools%20and%20Techniques%20">Buy the book!

Have you bought your copy?

Contact information for the Software Process and Measurement Cast

Email:  spamcastinfo@gmail.com
Voicemail:  +1-206-888-6111
Website: www.spamcast.net
Twitter: www.twitter.com/tcagley
Facebook:  http://bit.ly/16fBWV

Next!

SPaMCAST 171 will feature a bit of meta-cast celebrating the Software Process and Measurement Casts fifth anniversary and an entry from the Metrics Minute on Customer Satisfaction!

Categories: Process Management

Playing around with pomodoros

Mark Needham - Sun, 01/22/2012 - 22:25

Over the last 3/4 months I’ve been playing around with the idea of using pomodoros to track all coding/software related stuff that I do outside of work.

I originally started using this technique while I was doing the programming assignments for ml-class because I wanted to know how much time I was spending on it each week and make sure I didn’t run down rabbit holes too often.

One interesting observation that I noticed from keeping the data of these pomodoros was that while during the early programming assignments it would take me 7 or 8 pomodoros to finish, by the end it was down to around 4.

I think this was due to the difficulty of the assignments decreasing as time went on, I didn’t improve that dramatically!

As I mentioned a few weeks ago I’ve also been using pomodoros in combination with a yak stack to make sure I don’t go off track and it’s been interesting applying the technique while trying to solve a problem I’m having with using the Jersey client on Android.

It’s such a fiddly problem and splitting my time into 25 minute slots has forced me to create a plan for what I’m going to try and do in that pomodoro, whether it be ruling out an approach or trying to understand the underlying code that isn’t working.

I haven’t been successful in solving my problem but I’m pretty sure that I’ve spent much less time trying to solve it than I would have otherwise. I can certainly imagine spending hours aimlessly trying things that have no chance of working.

One thing I’ve been experimenting with is reducing the length of the pomodoro to 15 minutes when I know there’s something specific that I want to investigate and I’m fairly sure it won’t take a full length pomodoro.

Previously I would end up just killing time for 10 minutes or just resetting the pomodoro because I didn’t have anything else to do.

I generally enjoy coding much more by applying this time constraint and I think the reason for that is explained by The Progress Principle, which I’m currently reading:

If people are in an excellent mood at the end of the day, it’s a good bet that they have made some progress in their work. If they are in a terrible mood, it’s a good bet that they have had a setback.

To a great extent, inner work life rises and falls with progress and setbacks in the work. This is the progress principle

Using a pomodoro seems to reduce the amount of time that is spent dealing with setbacks and it creates frequent opportunities to discard an approach you’re taking if it’s clear that it’s not going anywhere.

A disadvantage that I’ve sometimes felt when working on the Jersey/Android problem is that I really don’t want to spend 25 minutes working on it because I’ve been getting absolutely nowhere with it for about 6/7 pomodoros now.

I’d rather delude myself that I’m going to magically fix it just by fiddling around with the code for an indeterminate period of time!

In a way constraining coding in this way does take some of the fun out of it as well because it’s now more structured and you tend to have fun when you’re just randomly doing stuff and lose track of time.

On the other hand I probably end up doing a lot more of the stuff I want to do when I constrain it in this way!

Decisions, decisions…

Categories: Programming

What Now for Internet Piracy?

Software Architecture Zen - Pete Cripp - Sun, 01/22/2012 - 21:40
So SOPA is to be kicked into the long grass which means it is at least postponed if not killed altogether. For those who have not been following the Stop Online Piracy Act debate, this is the bill proposed by a U.S Republican Representative to expand the ability of U.S. law enforcement to fight online trafficking in copyrighted intellectual property (IP) and counterfeit goods. Supporters of SOPA said it would protect IP as well as the jobs and livelihoods of people (and organisations) involved in creating books, films music, photographs etc. Opponents reckoned the legislation threatened free speech and innovation and would enable law enforcement officers to block access to entire internet domains as well as violating the First Amendment. Inevitably much of the digerati came out in flat opposition of SOPA and staged an internet blackout on 18th January where many sites "went dark" and Wikipedia was unavailable altogether. Critics of SOPA cited that the fact the bill was supported by the music and movie industry was an indication that it was just another way of these industry dinosaurs protecting their monopoly over content distribution. So, a last minute victory for the new digital industry over the old analogue one?

And yet...

Check out this TED talk by digital commentator Clay Shirky called Why SOPA is a bad idea. Shirky in his usual compelling way puts a good case for why SOPA is bad (the talk was published before the recent announcement on the bill being postponed) but the real interest for me in this talk was from the comments about it. There are many people saying yes SOPA may be a bad bill but there is nonetheless a real problem with content being given away that should otherwise be paid for and that content creators (whether they be software developers, writers or photographers) are simply losing their livelihoods because people are stealing their work. Sure, there are copyright laws that are meant to prevent this sort of thing happening but who can really chase down the web sites and peer-to-peer networks that "share" content they have not created or paid for? SOPA may have been a bad bill and really have been about protecting the interests of large corporations who just want to carry on doing what they have always done without having to adapt or innovate. However without some sort of regulation that protects the interests of individuals or small start-ups wishing to earn a living from their art, killing SOPA has not moved us forward in any way and certainly not protected their interests. Unfortunately some sort if internet regulation is inevitable.

For a historical perspective of why this is likely to be so, see the TED talk by the Liberal Democrat Paddy Ashdown called The global power shift. Ashdown argues that "where power goes governance must follow" and that there is plenty of historical evidence showing what happens when this is not the case (the recent/current financial meltdown to name but one).

So SOPA may be dead but something needs to replace it and if we are to get the right kind of governance we must all participate in the debate else the powerful special interest groups will get their own way. Clay Shirky argued that if SOPA failed to be passed it would be replaced by something else. Now then is our chance to ensure that whatever that is, is right for content creators as well as distributors.

Categories: Architecture

Fridaygram: don’t censor the web, rediscovering Darwin, beautiful nebula

Google Code Blog - Fri, 01/20/2012 - 22:26
Author Photo
By Scott Knaster, Google Code Blog Editor

Last Wednesday, the web looked very different than it usually does. Dozens of popular sites went dark or were modified in some way. We censored the logo on our homepage. As you probably know by now, all this was done to call attention to prospective legislation being debated by the U.S. Congress: the Stop Online Piracy Act (SOPA) and the PROTECT IP Act (PIPA). These bills would censor the web, eliminate due process, and despite their titles, would not stop piracy.

We asked you to take action by signing a petition to Congress, and you responded. More than 7 million people in the U.S. added their names to the petition. We’re asking you to please keep sharing the petition with your friends at http://www.google.com/takeaction.

Let’s go from the U.S. Congress to the British Geological Survey, where Howard Falcon-Lang recently discovered a wooden cabinet tucked away in a corner. Inside the cabinet were rock samples with the signature C. Darwin, Esquire. As in Charles Darwin. It turns out that these samples were collected by Darwin during his HMS Beagle voyages in the 1830s, and had been misplaced for 165 years. Probably they’ll keep better track of the Darwin samples now.

Finally, for something that’s just really cool, please take a look at this video that zooms into an image of the Helix Nebula in the constellation Aquarius. Enjoy!




Fridaygram posts are generally just for fun, although we’ve put on our serious hat for the main item today. Fridaygrams are designed for your Friday afternoon and weekend enjoyment. Each Fridaygram item must pass only one test: it has to be interesting to us nerds.
Categories: Programming

Stuff The Internet Says On Scalability For January 20, 2012

If you’ve got the time, we’ve got the HighScalability:

To read much more the Internet has to say on Scalability, please click below...
Categories: Architecture

Drum Roll: Public Workshop April 17-18, 2012

I’m so pleased to announce that Shane Hastie and I are leading a workshop on Working Effectively In Geographically Distributed Agile Project Teams, April 17-18, 2012 in Pleasanton, CA. Yes, that is Elisabeth Hendrickson’s Agilistry Studio.

Shane and I first delivered this workshop last year in Australia, when I was there for Software Education‘s SDC. We had a great time, and so did many of the participants. We have since evolved the workshop, to address the needs of the participants who did not have a great time, and to make sure we covered the topics we need to cover.

This is an experiential workshop. You will learn by doing and debriefing. If you’ve taken my one-day versions over the past year, you’ve had a taste of what we do in the two-day. You will learn even more from both of us. Remember, we developed this as a geographically distributed pair.

One of the benefits of signing up for the workshop is the informal consulting you can obtain, not just from us, but from the other people there. You’ll hear what other people are doing, what’s working and what’s not working. If you want, you can hear from Shane and me about what’s working and not working at our clients as they transition to agile and explore more agile approaches.

Do check out the syllabus. And, if you’re ready to sign up, please register.

Categories: Project Management