Skip to content

Companies

Hands-on Test Automation Tools session wrap up - Part1

Xebia Blog - Sun, 09/21/2014 - 16:57

Last week we had our first Hands-on Test Automation sessions.
Developers and Testers were challenged to show and tell their experiences in Test Automation.
That resulted in lots of in depth discussions and hands-on Test Automation Tool shoot-outs.

In this blogpost we'll share the outcome of the different sessions, like the famous Cucumber vs. FitNesse debat.

Stay tuned for upcoming updates!

Test Automation Frameworks

The following Test Automation Frameworks were demoed and discussed

1. FitNesse

FitNesse is a test management and execution tool.
You'll have to write/use fixture code if you want to use Selenium / WebDriver, webservices and databases in your tests.

Pros and Cons
You can have a good drill down in test results.
You can make use of scenario's and scenario libraries to make test automation steps reusable.
But refactoring is hard when scenario's are used extensively since there is no IDE support (yet)

2. Cucumber

Cucumber is a specification tool which describes how software should behave.
You'll have to write/use step definitions if you want to use Selenium / WebDriver, webservices and databases in your tests.

Pros and Cons
Cucumber forces you to write specifications / tests with scenarios (Behaviour in human readable language).
You can drill down into test results, but you'll need reporting libraries like Cucumber Reporting
We recommend using IntelliJ IDEA with the Cucumber plugin since it supports Cucumber seamlessly.
Refactoring becomes less problematic since you're using a IDE.

3. Selenium / WebDriver IDE

Selenium / WebDriver automates human interactions with web browser.
With the Selenium IDE you can record and play your tests in Firefox

Pros and Cons
It can get you started very quickly. You can record and play your tests scripts without writing any code.
Reusability of test automation code is not possible. You'll need to export it into an IDE to introduce reusability.

Must haves in Test Automation Tools

During the parallel sessions we've collected the following must haves in test automation tools.

Testers and Developers becoming best friends

When developers do not feel comfortable with the test automation tool, testers will try to fill the gap all by themselves. Most of the time these efforts result in hard to maintain test automation code. At some point in time test automation will become a bottleneck in Continuous Delivery. When picking a test automation tool consider each other's needs and pick a tool together. Feeling comfortable in writing and maintaining test automation code is really important to make test automation beneficial.

Separating What from How

Tools like FitNesse and Cucumber were designed to separate the What from the How in test automation. When combining both in those tools, you'll end up getting lost in details and you'll lose focus of what you are testing.
Use tools like FitNesse and Cucumber to describe What you are testing and put all details about How you are testing in test automation code (like fixture code and step definitions)

Other interesting tools
  • Thucydides: Reporting tests and results (including functional coverage)
  • Vagrant: Provisioning System Under Test instances
  • Liquibase: Treating database schema changes as 'code'

Stay tuned for upcoming updates!

 

Categories: Companies

The Danger of Point Solutions

NetObjectives - Sun, 09/21/2014 - 14:58
The software development world has created several approaches to improving the work at the team level. These include eXtreme Programming, Scrum, Kanban, Kanban Method. While all of these solutions are based on some degree of reality, much of their organization and practices are based on the belief systems of their creators. I think we can get the best of what these all contribute not merely by...

[[ This is a content summary only. Visit my website for full links, other content, and more! ]]
Categories: Companies

Enough With Defending Approaches

NetObjectives - Sat, 09/20/2014 - 19:14
My banter on twitter about being unhappy with Scrum and the Kanban Method leaving things out is reasonably well known.  I very often exclaim that Scrum should be done within the context of lean (a 10+ year old rant) and that the Kanban Method must attend to teams (which it’s been deemed to be orthogonal too).  When I make my claims I usually hear that “these approaches are designed this way”....

[[ This is a content summary only. Visit my website for full links, other content, and more! ]]
Categories: Companies

Recommendations for Kanban Coaching Professional Masterclass

Recent attendees of the Masterclass tell you what they valued and why you should attend...

David's approach to training is truly unique. I now have a different lens to view my team's upstream work, current work in progress, and deeper knowledge on how to communicate risk without disrupting the flow of changes throughout the organization.  What David has created with his, Modern Management Framework, is a revolutionary way of thinking for an evolutionary way of change. Jay Paulson

 

read more

Categories: Companies

Installing Oracle on Docker (Part 1)

Xebia Blog - Fri, 09/19/2014 - 13:56

I’ve spent Xebia’s Innovation Day last August experimenting with Docker in a team with two of my colleagues and a guest. We thought Docker sounds really cool, especially if your goal is to run software that doesn’t require lots of infrastructure and can be easily installed, e.g. because it runs from a jar file. We wondered however what would happen if we tried to run enterprise-software, like an Oracle database. Software that is notoriously difficult to install and choosy about the infrastructure it runs on. Hence our aim for the day: install an Oracle database on CoreOS and Docker.

We chose CoreOS because of its small footprint and the fact that it is easily installed in a VM using Vagrant (see https://coreos.com/docs/running-coreos/platforms/vagrant/). We used default Vagrantfile and CoreOS files with one modification: $vb_memory = 2024 in config.rb which allows the Oracle’s pre installer to run. The config files we used can be found here: https://github.com/jvermeir/OraDocker/

Starting with a default CoreOS install we then implemented the steps described here: http://www.tecmint.com/oracle-database-11g-release-2-installation-in-linux/.
Below is a snippet from the first version of our Dockerfile (tag: b0a7b56).
FROM centos:centos6
# Step 1: Setting Hostname
ENV HOSTNAME oracle.docker.xebia.com
# Step 2
RUN yum -y install wget
RUN wget --no-check-certificate https://public-yum.oracle.com/public-yum-ol6.repo -O /etc/yum.repos.d/public-yum-ol6.repo
RUN wget --no-check-certificate https://public-yum.oracle.com/RPM-GPG-KEY-oracle-ol6 -O /etc/pki/rpm-gpg/RPM-GPG-KEY-oracle
RUN yum -y install oracle-rdbms-server-11gR2-preinstall

Note that this takes awhile because the pre installer downloads a number of CentOS packages that are missing in CoreOS.
Execute this in a shell:
vagrant up
vagrant ssh core-01
cd ~/share/docker
docker build -t oradocker .

This seemed like a good time to do a commit to save our work in Docker:
docker ps # note the container-id and substitute for the last parameter in the line below this one.
docker commit -m "executed pre installer" 07f7389c811e janv/oradocker

At this point we studiously ignore some of the advice listed under ‘Step 2’ in Tecmint’s install manual, namely adding the HOSTNAME to /etc/syconfig/network, allowing access to the xhost (what would anyone want that for?) and mapping an IP address to a hostname in /etc/hosts (setting the hostname through ‘ENV HOSTNAME’ had no real effect as far as we could tell). We tried that but it didn’t seem to work. Denying reality and substituting our own we just ploughed on…

Next we added Docker commands to the Dockerfile that creates the oracle user, copy the relevant installer files and unzip them. Docker starts by sending a build context to the Docker daemon. This takes quite some time because the Oracle installer files are large. There’s probably some way to avoid this, but we didn’t look into that. Unfortunately Docker copies the installer files each time you run docker -t … only to conclude later on that nothing changed.

The next version of our Dockerfile sort of works in the sense that it starts up the installer. The installer then complains about missing swap space. We fixed this temporarily at the CoreOS level by running the following commands:
sudo su -
swapfile=$(losetup -f)
truncate -s 1G /swap
losetup $swapfile /swap
mkswap $swapfile
swapon $swapfile

found here: http://www.spinics.net/lists/linux-btrfs/msg28533.html
This works but it doesn’t survive a reboot.
Now the installer continues only to conclude that networking is configured improperly (one of those IgnoreAndContinue decisions coming back to bite us):
[FATAL] PRVF-0002 : Could not retrieve local nodename

For this to work you need to change /etc/hosts which our Docker version doesn’t allow us to do. Apparently this is fixed in a later version, but we didn’t get around to testing that. And maybe changing /etc/sysconfig/network is even enough, but we didn't try that either.

The latest version of our work is on github (tag: d87c5e0). The repository does not include the Oracle installer files. If you want to try for yourself you can download the files here: ">http://www.oracle.com/technetwork/database/enterprise-edition/downloads/index-092322.html and adapt the docker file if necessary.

Below is a list of ToDo’s:

  1. Avoid copying large installer files if they’re not gonna be used anyway.
  2. Find out what should happen if you call ‘ENV HOSTNAME oracle.docker.xebia.com’.
  3. Make swap file setting permanent on CoreOS.
  4. Upgrade Docker version so we can change /etc/hosts

All in all this was a useful day, even though the end result was not a running database. We hope to continue working on the ToDo’s in the future.

Categories: Companies

Scaling Agile Your Way: SAFe vs. MAXOS (Part 2 of 4)

Agile Management Blog - VersionOne - Thu, 09/18/2014 - 23:03

In Part 1 of this four-part blog series, I explained why a cookie-cutter approach will not work as you undertake large-scale agile initiatives.  Each agile project developing a product or a solution has a unique context:  assumptions, situation, team members and their skill sets, organizational structure, management understanding and support, maturity of practices, challenges, culture, etc.

In Part 1, I proposed a fairly comprehensive list of 25 scaling agile parameters classified into six scaling aspects:

1.  Teams
2.  Customers/Users
3.  Agile Methods and Environments
4.  Product/Solution
5.  Complexity
6.  Value Chain (see Tables 1 through 4 of Part 1 of this blog series)

Each scaling agile parameter can assume one or more values from a range of values.  This comprehensive (but by no means, complete or exhaustive) list of 25 scaling agile parameters suggests that the agile scaling space is complex and rich with many choices.  Each organization or large-scale project is likely to select a different combination of these 25 scaling agile parameters that are relevant; moreover, the value or range of values for each scaling agile parameter for a project or an organization is likely to be unique.  However, in Part 1, I also clarified that “Scaling Agile Your Way” does not imply a license to optimize at the subsystem levels (teams or programs) at the expense of overall system-level optimization (portfolios and enterprise).  Systems thinking is important for Scaling Agile Your Way.

In Part 1, I presented a brief overview of various popular Agile and Lean scaling frameworks: Scaled Agile Framework® (SAFe™), LeSS, DAD and MAXOS.  Although there are differences among SAFe, LeSS and DAD, they all are radically different from MAXOS.  In this part of the series, I will compare and contrast SAFe vs. MAXOS in some depth.

Briefly, here are the key highlights of SAFe.  Details can be found at Scaled Agile Framework:

  • SAFe requires a “Portfolio, Program and Teams” hierarchy for a large-scale agile project.
  • Each team must be a cross-functional Scrum team and may follow many XP practices.
  • Epics at portfolio levels are managed as a Lean/Kanban flow.  Epics are broken down into features that can be completed in a single release cycle at the program level; each feature is broken down into stories that can be completed in a single sprint at the team level.
  • All teams in a release train of a program must follow the same lock-step sprint cadence (typically two weeks).
  • Release train planning requires all team members (typically up to 150) from all teams in a program to hold two-day-long release planning meetings in person, which entails a substantial effort and complex logistics.
  • Release cycles are typically eight to 12 weeks long.
  • Software is developed on sprint cadence, and released on demand (but cannot be released faster than the sprint cadence).
  • Considerable time and effort is spent in various ceremonies:  sprint planning, sprint review and sprint retrospectives, release train planning across multiple teams, release review and release retrospectives, etc.

Briefly, here are the highlights of MAXOS.  Details can be found in Andy Singleton’s Agile 2014 presentation.

  • MAXOS is the scaling approach for “Continuous Agile.”  Continuous Agile combines Kanban Agile task management with continuous delivery code management. 
  • MAXOS requires a number of (almost) independent service teams.
  • Services have well-defined APIs, are loosely coupled, and have minimal dependencies among them.
  • Each team operates with Lean flow.  Applications are rapidly composed of a group or a network of services.
  • Each team is developer-centric (not cross-functional) and highly empowered.
  • Code is continually integrated in a single code base across all teams.
  • Code is continually tested with automated tests (unit, acceptance, regression, etc.) by firing off as many virtual machines as needed in a cloud-based environment.
  • Any dependency issues across teams are immediately resolved via rapid team-to-team communication.  For rapid team-to-team or member-to-member communication, tool support is essential. VersionOne provides excellent communication and collaboration among team members.
  • The typical ratio of developers to testers tends to be 10:1, as teams are developer-centric and developers do most automated testing.   There are no separate QA teams.  QA testers are called as needed for their expertise by developer-centric teams.
  • Each empowered, developer-centric team decides when to release its code (not decided by QA testers or product managers!).  MAXOS claims that this policy rationally aligns the interests of developers with consequences of their release decision; poorly written, poorly reviewed, or inadequately tested code may mean “no weekends” or “No Friday evening beer” for developers!
  • All features or stories have switches (togglers) that the product owner (called story owner) decides to turn on (unblock) or turn off (block) based on the market needs.
  • Code released in production is extensively supported by automated user feedback collection, measurements and analysis that result in actionable reports for product management.
  • Automated feedback from production environment is also used directly by developers to immediately fix problems.
  • Meeting time is minimized by “automating away” management meetings, and removing or reducing other Scrum ceremonies.  For example, sprint and release retrospectives are replaced by periodic “Happiness Surveys” and taking actions based on those surveys.

Because of these fundamental differences between SAFe and MAXOS, they represent radically different approaches to scaling agile. The contrast between SAFe and MAXOS is breathtaking, and its implications are worth understanding.  Tables 5-10 present the differences between SAFe and MAXOS from the perspective of 25 scaling agile parameters covered in Tables 1-4 of Part 1.

These six tables (Tables 5-10 below) follow a specific color legend described below:

B_Legend

Table5a

Table6a

Table7a

Table8a

Table9a

Table10a

Are your agile projects closer to the SAFe Sweet Spot or the MAXOS Sweet Spot? 

Or are your projects closer to the SAFe Challenge Zone or the MAXOS Challenge Zone?  Or are you in a situation where neither SAFe nor MAXOS will serve you unique agile scaling needs? If you are exploring the use of LeSS or DAD framework, I would encourage you to use the list of 25 scaling agile parameters to identify the Sweet Spot, Challenge Zone and Unfit Zone for LeSS or DAD (as I have done in Tables 5-10 for SAFe and MAXOS). Then determine if your projects are closer to the Sweet Spot or Challenge Zone of LeSS or DAD.

I would love to hear from you either in the Comments below, by email (Satish.Thatte@VersionOne.com), or on Twitter @smthatte.

Related posts:

Part 1: Scaling Agile Your Way: Agile Scaling Aspects and Context Matter Greatly

Part 3: Scaling Agile Your Way – Sweet Spot, Challenge Zone and Unfit Zone for SAFe and MAXOS

Part 4: Scaling Agile Your Way – How to develop and implement your custom approach

Categories: Companies

Who owns the meetings in Scrum?

Growing Agile - Thu, 09/18/2014 - 14:31

We are coaching a new team to use Scrum, and a question has popped up about who owns the various meetings in Scrum. Many people think that because the ScrumMaster is responsible for the process, they own all the Scrum meetings. If that’s you, just pause and go on a thought journey with me.

One of our favourite sayings is:

You do it, you own it

The ScrumMaster is a facilitator in the majority of Scrum meetings – but does that make them an owner? If the ScrumMaster is the one scheduling all the meeting and taking notes etc – then they own the meeting. Scrum is not the ScrumMasters process. They are merely there to guide and coach the teams and Product Owners. Let me explain each meeting.

Backlog Grooming (or Backlog Refinement)

The outcome of this meeting is that the team has a better understanding of requirements and that stories are sized. The person who needs the estimates, and will be explaining the requirements is the Product Owner. The ScrumMaster ensures everyone is on the same page, checks the time box and perhaps structures the meeting – this is a facilitative role. The ScrumMaster should not be contributing to the content of the meeting.

Sprint Planning Part 1

This meeting is to check understanding and make a commitment for the sprint. Once again, the Product Owner is really interested in this outcome. The ScrumMaster is a facilitator.

Sprint Planning Part 2

This meeting is for the team to design and chat about how they are going to do each story. This meeting is for the team. The ScrumMaster can facilitate this, or they can ask the team to facilitate this. However, unless someone in the team has facilitation experience, I would suggest this be the ScrumMaster.

Daily Scrum

This is for the team to checkin with each other and their commitment. So the team own it. The ScrumMaster is there as a facilitator only, and occasionally should let the team do their own facilitation.

Sprint Review

This meeting is about the product/project and where you are as a team with the release. The Product Owner cares about this and therefore owns this meeting. The ScrumMaster facilitates. And remember facilitation means not adding any content!

Sprint Retrospective

This meeting is about the process of the team. It is for the team and should be owned by them. The ScrumMaster is the impartial facilitator.

 Who owns the meetings in Scrum?

Should the facilitator or owner for any meeting not be available (maybe they are off sick or on training) then decide at the start of the meeting who will play which role. It is not a good idea for a facilitator (who should be impartial) to own and run a meeting.

My personal preference is to have the owner of the meeting schedule the meeting and NOT the ScrumMaster. Let the people who need the meeting own it. If you’re a ScrumMaster and you currently schedule all the meetings, explain why you don’t want to do this anymore and ask someone else to schedule the meetings important to them. Remember “You do it, you own it!”.

Categories: Companies

Full width iOS Today Extension

Xebia Blog - Thu, 09/18/2014 - 11:57

Apple decided that the new Today Extensions of iOS 8 should not be the full width of the notification center. They state in their documentation:

Because space in the Today view is limited and the expected user experience is quick and focused, you shouldn’t create a widget that's too big by default. On both platforms, a widget must fit within the width of the Today view, but it can increase in height to display more content.

Source: https://developer.apple.com/library/ios/documentation/General/Conceptual/ExtensibilityPG/NotificationCenter.html

This means that developers that create Today Extensions can only use a width of 273 points instead of the full 320 points (for iPhones pre iPhone 6) and have a left offset of the remaining 47 points. Though with the release of iOS 8, several apps like DropBox and Evernote do seem to have a Today Extension that uses the full width. This raises question wether or not Apple noticed this and why it came through the approval process. Does Apple not care?

Should you want to create a Today Extension with the full width yourself as well, here is how to do it (in Swift):

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    if let superview = view.superview {
        var frame = superview.frame
        frame = CGRectMake(0, CGRectGetMinY(frame), CGRectGetWidth(frame) + CGRectGetMinX(frame), CGRectGetHeight(frame))
        superview.frame = frame
    }
}

This changes the super view (Today View) of your Today Extension view. It doesn't use any private Api's, but Apple might reject it for not following their rules. So think carefully before you use it.

Categories: Companies

Become high performing. By being happy.  

Xebia Blog - Thu, 09/18/2014 - 04:59

The summer holidays are over. Fall is coming. Like the start of every new year, a good moment for new inspiration.

Recently, I went twice to the Boston area for a client of Xebia. I met there (I dislike the word “assessments"..) a number of experienced Scrum teams. They had an excellent understanding of Scrum, but were not able to convert this to an excellent performance. Actually, there were somewhat frustrated and their performance was slightly going down.

So, they were great teams, great team members, their agile processes were running smoothly, but still not a single winning team. Which left in my opinion only one option: a lack of Spirit.   Spirit is the fertilizer of Scrum and actually every framework, methodology and innovation.  But how to boost the spirit?

Screen Shot 2014-09-17 at 10.43.43 PM Until a few years ago, I would “just" organize teambuilding sessions to boost this, parallel with fixing/escalating the root causes. Nobel, but far from effective.   It’s much more about mindset en happiness and taking your own responsibility there.   Let’s explain this a little bit more here.

This are definitely awkward times. Terrible wars and epidemics where we can’t turn our back from anymore, an economic system which hardly survives, a more and more accelerating and a highly demanding society. In all which we have to find “time” for our friends, family, yourself and job or study. The last ones are essential to regain balance in a more and more depressing world. But how?

One of the most important building blocks of the agile mindset and life is happiness. Happiness is the fuel of acceleration and success. But what is happiness? Happiness is the ultimate moment you’re not thinking, but enjoying the moment and forget the world around you. For example, craftmanship will do this with you. Losing track of time while exercising the craft you love.

But too often we prevent our selves from being happy. Why should I be happy in this crazy world?   With this mentality you’re kept hostage by your worrying mind and ignore the ultimate state you were born: pure, happy ready to explore the world (and make mistakes!). It’s not a bad thing to be egocentric sometimes and switch off your dominant mind now and then. Every human being has the state of mind and ability to do this. But too rarely we do.

On the other hand, it’s also not a bad thing to be angry, frightened or sad sometimes. These emotions will help enjoying your moments of happiness more. But often your mind will resist these emotions. They are perceived as a sign of weakness or as a negative thing you should avoid. A wrong assumption. The harder you're trying to resist these emotions, the longer they will stay in your system and prevent you from being happy.

Being aware of these mechanisms I’ve explained above, you’ll be happier, more productive and better company for your family, friends and colleagues. Parties will not be a forced way trying to create happiness anymore, but a celebration of personal responsibility, success and happiness.

Categories: Companies

Continuous Delivery is about removing waste from the Software Delivery Pipeline

Xebia Blog - Wed, 09/17/2014 - 16:44

On October the 22nd I will be speaking at the Continuous Delivery and DevOps Conference in Copenhagen where I will share experiences on a very successful implementation of a new website serving about 20.000.000 page views a month.

Components and content for this site were developed by five(!) different vendors and for this project the customer took the initiative to work according to DevOps principles and implement a fully automated Software Delivery Process as they went along. This was a big win for the project, as development teams could now focus on delivering new software instead of fixing issues within the delivery process itself and I was the lucky one to implement this.

This blog is about visualizing the 'waste' we addressed within the project where you might find the diagrams handy when communicating Continuous Delivery principles within your own organization.

To enable yourself to work according to Continuous Delivery principles, an effective starting point is to remove waste from the Software Delivery Process. If you look at a traditional Software Delivery Process you'll find that there are probably many areas in your existing process that do not add any value for the customer at all.

These area's should be seen as pure waste, not adding any value to your customer, costing you either time or money (or both) over-and-over-and-over again. Each time new features are being developed and pushed to production, many people will perform a lot of costly manual work and run into the same issues over and over again. The diagram below provides an example of common area's where you might find waste in your existing Software Development Pipeline. Imagine this process to repeat every time a development team delivers new software. Within your conversation, you might want to an equal diagram to explain pain points within your current Software Delivery Process.

a traditional software delivery process

a traditional software delivery process

Automation of the Software Delivery process within this project, was all about eliminating known waste as much as possible. This resulted in setting up an Agile project structure and start working according to DevOps principles, enabling the team to deliver software on a frequent basis. Next to that, we automated the central build with Jenkins CI, which checks out code from a Git Version Management System, compiles code using maven, stores components in Apache Archiva, kicks off static, unit and functional tests covering both the JEE and PHP codebase and creating Deployment Units for further processing down the line. Deployment Automation itself was implemented by introducing XL Deploy. By doing so, every time a developer pushed new JEE or PHP code into the Git Version Management System, freshly baked deployment units were instantly deployed to the target landscape, which in its turn was managed by Puppet. An abstract diagram of this approach and chosen tooling is provided below.

overview of tooling for automating the software delivery process

overview of tooling for automating the software delivery process

When paving the way for Continuous Delivery, I often like to refer to this as working on the six A's: Setting up Agile (Product Focused) Delivery teams, Automating the build, Automating tests, Automating Deployments, Automating the Provisioning Layer and clean, easy to handle Software Architectures. The A for Architecture is about making sure that the software that is being delivered actually supports automation of the Software Delivery Process itself and put's the customer in the position to work according to Continuous Delivery principles. This A is not visible in the diagram.

After automation of the Software Delivery Process, the customer's Software Development Process behaved like the optimized process below, providing the team the opportunity to push out a constant & fluent flow of new features to the end user. Within your conversation, you might want to use this diagram to explain advantages to your organization.

an optimized software delivery process

an optimized software delivery process

As we automated the Software Delivery Pipeline for the customer we positioned this customer to go live at a press of a button. And on the go-live date, it was just that: a press of the button and 5 minutes later the site was completely live, making this the most boring go-live event I've ever experienced. The project itself was real good fun though! :)

Needless to say that subsequent updates are now moved into live state in a matter of minutes as the whole process just became very reliable. Deploying code just became a non-event. More details on how we made this project a complete success, how we implemented this environment, the project setting, the chosen tooling along with technical details I will happily share at the Continuous Delivery and DevOps Conference in Copenhagen. But of course you can also contact me directly. For now, I just hope to meet you there..

Michiel Sens.

Categories: Companies

What is Card Size and Why Does it Matter?

Many teams find it useful to identify and track the size — or amount of work — associated with each work item. LeanKit lets you easily assign a size value to each card,  manage your WIP based on card size, and run reports using size as a variable. In LeanKit, size is an optional field that you […]

The post What is Card Size and Why Does it Matter? appeared first on Blog | LeanKit.

Categories: Companies

One week sprint, 45 minute Retrospective plan

Growing Agile - Tue, 09/16/2014 - 14:19

We are currently helping out at a client, and I found myself in the ScrumMaster role icon smile One week sprint, 45 minute Retrospective plan It’s been a while! They run one week sprints and their teams are 1 or 2 people and they change every month or so. This seems to work for them on the most part. I need to run a retrospective for two teams at the same time. One team of 2 people and one team of one. As I haven’t been able to clone myself as yet, this needed to happen together, but allow each team to reach their own improvement point.

The Plan:

OneWeekRetroPlan1 One week sprint, 45 minute Retrospective plan

 

 

How did this work in reality?

The person on the team of one was off sick, so the retro ended up being just for one team of two – this made it a bit easier to facilitate and interact with the team.

The rest of this feedback came from the Plus/Delta exercise. It shows how important it is as a facilitator to get feedback from your team.

This team usually does the same retro every week (same activities), so the different activities felt a bit weird to them. I’m a bit surprised I fell into this trap, I do know better icon smile One week sprint, 45 minute Retrospective plan If your team is used to doing something only change one activity at a time, changing everything makes them feel a bit unsettled and uncomfortable.

They enjoyed the first exercise (Check In) but felt it didn’t lead anywhere – so perhaps a Diverge section that flows from it will be better.

They enjoyed the questions as it made them really think. They did miss not having a timeline activity to remind them of what happened over the week of their sprint.

They liked getting to one action that is very solid and they know will do. They are used to having a list of goals they want to achieve during the sprint.

Thank you Concetta and Wilhelm!

photo 22 e1410510576487 225x300 One week sprint, 45 minute Retrospective plan

 

 

 

Categories: Companies

Care about business strategy? - Tune to this channel...

Improving projects with xProcess - Tue, 09/16/2014 - 13:08
If you think the principles and values of agile extend beyond the narrow boundaries of software development teams to organisations and corporate cultures, I think, like me, you'll be inspired by a couple of presentations from the recent Agile On The Beach conference, They are great bedtime viewing (for when you've finally had enough of Bakeoff!).

Firstly a video from Tom Sedge: TDD for Business Strategies – Developing Business Strategies Test-First.
Tom Sedge provides very practical advice on how to define mission (why we're here - our purpose and driving cause), vision (where we're heading - how the world will be different), goals (what we want - destinations or desired outcomes), and strategies (how we will get there - potential routes to the destination). His examples of good (Tesla, SpaceX) and bad (Kodak) missions/visions are particularly helpful. How could the inventor of the digital camera go bust, just as digital photography exploded on scene, particularly as their founder George Eastman expressed his vision in the 1880's as "a world where the camera is as convenient as the pencil". These days I quite often wish I had a pencil on me, yet I always have a camera! His vision makes a sad contrast with Kodak's mission and vision statement from the early 2000's - a paragraph of unmemorable platitudes about customer focus and shareholder value, that no one outside the company would care a fig about!


The second one is from Bjarte Bogsnes, Vice President of Performance Management Development at the major international oil company, Statoil. It's on Beyond Budgeting – an agile management model for new business and people realities. If you give it a listen you'll understand why (even though I think budgets are essential) I'm not that keen on investing much time in annual budgeting. In his words, the approach "... is about rethinking how we manage organisations in a post-industrial world, where innovative management models represent the only sustainable competitive advantage ... releasing people from the burdens of stifling bureaucracy and suffocating control systems, trusting them with information and giving them time to think, reflect, share, learn and improve."

Remember he's talking about a massive oil company - not the easiest place to introduce agile thinking! Gives hope to the rest of us.

Categories: Companies

How to Run Effective Standups and Retrospectives

Step three of The Kanban Roadmap: How to Get Started in 5 Steps As a systems-thinking methodology, Kanban calls for team members to take collective responsibility for team priorities. Rich conversations about the work are a must-have. They help the team discover bottlenecks, resolve issues, focus on flow, and continuously improve their process. To facilitate […]

The post How to Run Effective Standups and Retrospectives appeared first on Blog | LeanKit.

Categories: Companies

An Agile Journey Through Japan

Danube - Mon, 09/15/2014 - 19:18

Agile Development vs. Enterprise Agility in Japan’s Embedded Software Development

This week I happened to reread an article sent to me by André Girard, a Senior Analyst at VDC Research.  Interestingly, I read in on my way from Tokyo to Bangalore after a week of great meetings in Japan visiting prospects, partners and clients.  I was also in Japan to launch a major partnership in Japan with Hitachi Solutions to provide joint offerings in the DevOps IT market, as well as the embedded SW development space.  For those of you who are better than me at Japanese, take a look at the bottom of this article at some of the press we received within 8 hours of announcing this partnership on September 12th.

Andre and VDC specialize in analyzing advancements and trends in embedded software development.  In Andre’s article he sent to me, I repeatedly saw reinforcement of several of the points he made in a dozen+ meetings over 6 days:

-          Increasing interest in agile overall – at all levels of the company

-          A need to codify agile processes with tools to build repeatable processes

-          A need to have an adaptive, learning and scaling set of tools and processes

However, one difference that I saw in Japan is that agile development, although being widely adopted, is still being driven bottom up. In sharp contrast, in Europe and the US, agile and more importantly “business agility” has almost become an executive strategic imperative.   Towards that end and to strong interest, CollabNet recently codified our 15 years of experience in helping companies transform from distributed and isolated to agile, collaborative and leveraged into a straightforward and practical “Blueprint for Enterprise Agility”, based on the open and adaptive CollabNet TeamForge platform.

This Blueprint for business agility was quite an eye opener for the clients and prospects we met with in Japan.  The reason is that executive awareness and focus on overall enterprise agility is not yet the case in many traditional companies in Japan, where senior management is still struggling with their more structured ways of working across an organization.  CollabNet’s partnership with Hitachi is geared at accelerating this IT and embedded SW development transformation in Japan from developer driven agile development activities to executive results focused business agility.

On a positive side, I did see this executive awareness of the need for organizational wide agility in some of the younger Japanese companies.  If the press and strong reception we received at multiple large companies is any indication, the market in Japan may be waking up to what we are already seeing in other parts of the world.

Also, be sure to join me Thursday September 17th for a webinar on How To Scale Application Development & Delivery Across the Enterprise.  You can register here.

Bill

PS.  And for those fluent in Japanese, or just want to look at the pictures, read on!

http://cloud.watch.impress.co.jp/docs/news/20140912_666586.html

http://itpro.nikkeibp.co.jp/atcl/news/14/091200867/

http://codezine.jp/article/detail/8113

http://www.excite.co.jp/News/column_g/20140912/Cobs_042028.html

http://enterprisezine.jp/article/detail/6150

http://headlines.yahoo.co.jp/hl?a=20140912-00000105-impress-sci

http://sankei.jp.msn.com/economy/news/140912/prl14091216020133-n1.htm

The post An Agile Journey Through Japan appeared first on blogs.collab.net.

Categories: Companies

Agile Games at Agile Open Southern California

Agile Learning Labs - Sun, 09/14/2014 - 04:55

Our very own Laura Powers recently participated in Agile Open Southern California, where she was interviewed by Scott Dunn. Laura talks about the power of games to help executives understand the changes they need to make in order for their organizations to become more agile.

The video was put together by Cliff Rosa of Rosa Media Productions.

Categories: Companies

iOS Today Widget in Swift - Tutorial

Xebia Blog - Sat, 09/13/2014 - 19:51

Since both the new app extensions of iOS 8 and Swift are both fairly new, I created a sample app that demonstrates how a simple Today extension can be made for iOS 8 in Swift. This widget will show the latest blog posts of the Xebia Blog within the today view of the notification center.

The source code of the app is available on GitHub. The app is not available on the App Store because it's an example app, though it might be quite useful for anyone following this Blog.

In this tutorial, I'll go through the following steps:

New Xcode project

Even though an extension for iOS 8 is a separate binary than an app, it's not possible to create an extension without an app. That makes it unfortunately impossible to create stand alone widgets, which this sample would be since it's only purpose is to show the latest posts in the Today view. So we create a new project in Xcode and implement a very simple view. The only thing the app will do for now is tell the user to swipe down from the top of the screen to add the widget.

iOS Simulator Screen Shot 11 Sep 2014 23.13.21

Time to add our extension target. From the File menu we choose New > Target... and from the Application Extension choose Today Extension.

Screen Shot 2014-09-11 at 23.20.34

We'll name our target XebiaBlogRSSWidget and of course use Swift as Language.

XebiaBlogRSS

The created target will have the following files:

      • TodayViewController.swift
      • MainInterface.storyboard
      • Info.plist

Since we'll be using a storyboard approach, we're fine with this setup. If however we wanted to create the view of the widget programatically we would delete the storyboard and replace the NSExtensionMainStoryboard key in the Info.plist with NSExtensionPrincipalClass and TodayViewController as it's value. Since (at the time of this writing) Xcode cannot find Swift classes as extension principal classes, we also would have to add the following line to our TodayViewController:

@objc (TodayViewController)

Update: Make sure to set the "Embedded Content Contains Swift Code" build setting of the main app target to YES. Otherwise your widget written in Swift will crash.

Add dependencies with cocoapods

The widget will get the latest blog posts from the RSS feed of the blog: http://blog.xebia.com/feed/. That means we need something that can read and parse this feed. A search on RSS at Cocoapods gives us the BlockRSSParser as first result. Seems to do exactly what we want, so we don't need to look any further and create our Podfile with the following contents:

platform :ios, "8.0"

target "XebiaBlog" do

end

target "XebiaBlogRSSWidget" do
pod 'BlockRSSParser', '~> 2.1'
end

It's important to only add the dependency to the XebiaBlogRSSWidget target since Xcode will build two binaries, one for the app itself and a separate one for the widget. If we would add the dependency to all targets it would be included in both binaries and thus increasing the total download size for our app. Always only add the necessary dependencies to both your app target and widget target(s).

Note: Cocoapods or Xcode might give you problems when you have a target without any Pod dependencies. In that case you may add a dependency to your main target and run pod install, after which you might be able to delete it again.

The BlockRSSParser is written in objective-c, which means we need to add an objective-c bridging header in order to use it from Swift. We add the file XebiaBlogRSSWidget-Bridging-Header.h to our target and add the import.

#import "RSSParser.h"

We also have to tell the Swift compiler about it in our build settings:

Screen Shot 2014-09-12 at 15.35.21

Load RSS feed

Finally time to do some coding. The generated TodayViewController has a function called widgetPerformUpdateWithCompletionHandler. This function gets called every once in awhile to ask for new data. It also gets called right after viewDidLoad when the widget is displayed. The function has a completion handler as parameter, which we need to call when we're done loading data. A completion handler is used instead of a return function so we can load our feed asynchronously.

In objective-c we would write the following code to load our feed:

[RSSParser parseRSSFeedForRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://blog.xebia.com/feed/"]] success:^(NSArray *feedItems) {
  // success
} failure:^(NSError *error) {
  // failure
}];

In Swift this looks slightly different. Here the the complete implementation of widgetPerformUpdateWithCompletionHandler:

func widgetPerformUpdateWithCompletionHandler(completionHandler: ((NCUpdateResult) -> Void)!) {
  let url = NSURL(string: "http://blog.xebia.com/feed/")
  let req = NSURLRequest(URL: url)

  RSSParser.parseRSSFeedForRequest(req,
    success: { feedItems in
      self.items = feedItems as? [RSSItem]
      completionHandler(.NewData)
    },
    failure: { error in
      println(error)
      completionHandler(.Failed)
  })
}

We assign the result to a new optional variable of type RSSItem array:

var items : [RSSItem]?

The completion handler gets called with either NCUpdateResult.NewData if the call was successful or NCUpdateResult.Failed when the call failed. A third option is NCUpdateResult.NoData which is used to indicate that there is no new data. We'll get to that later in this post when we cache our data.

Show items in a table view

Now that we have fetched our items from the RSS feed, we can display them in a table view. We replace our normal View Controller with a Table View Controller in our Storyboard and change the superclass of TodayViewController and add three labels to the prototype cell. No different than in iOS 7 so I won't go into too much detail here (the complete project is on GitHub).

We also create a new Swift class for our custom Table View Cell subclass and create outlets for our 3 labels.

import UIKit

class RSSItemTableViewCell: UITableViewCell {

    @IBOutlet weak var titleLabel: UILabel!
    @IBOutlet weak var authorLabel: UILabel!
    @IBOutlet weak var dateLabel: UILabel!

}

Now we can implement our Table View Data Source functions.

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  if let items = items {
    return items.count
  }
  return 0
}

Since items is an optional, we use Optional Binding to check that it's not nil and then assign it to a temporary non optional variable: let items. It's fine to give the temporary variable the same name as the class variable.

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
  let cell = tableView.dequeueReusableCellWithIdentifier("RSSItem", forIndexPath: indexPath) as RSSItemTableViewCell

  if let item = items?[indexPath.row] {
    cell.titleLabel.text = item.title
    cell.authorLabel.text = item.author
    cell.dateLabel.text = dateFormatter.stringFromDate(item.pubDate)
  }

  return cell
}

In our storyboard we've set the type of the prototype cell to our custom class RSSItemTableViewCell and used RSSItem as identifier so here we can dequeue a cell as a RSSItemTableViewCell without being afraid it would be nil. We then use Optional Binding to get the item at our row index. We could also use forced unwrapping since we know for sure that items is not nil here:

let item = items![indexPath.row]

But the optional binding makes our code saver and prevents any future crash in case our code would change.

We also need to create the date formatter that we use above to format the publication dates in the cells:

let dateFormatter : NSDateFormatter = {
        let formatter = NSDateFormatter()
        formatter.dateStyle = .ShortStyle
        return formatter
    }()

Here we use a closure to create the date formatter and to initialise it with our preferred date style. The return value of the closure will then be assigned to the property.

Preferred content size

To make sure we that we can actually see the table view we need to set the preferred content size of the widget. We'll add a new function to our class that does this.

func updatePreferredContentSize() {
  preferredContentSize = CGSizeMake(CGFloat(0), CGFloat(tableView(tableView, numberOfRowsInSection: 0)) * CGFloat(tableView.rowHeight) + tableView.sectionFooterHeight)
}

Since the widgets all have a fixed width, we can simply specify 0 for the width. The height is calculated by multiplying the number of rows with the height of the rows. Since this will set the preferred height greater than the maximum allowed height of a Today widget it will automatically shrink. We also add the sectionFooterHeight to our calculation, which is 0 for now but we'll add a footer later on.

When the preferred content size of a widget changes it will animate the resizing of the widget. To have the table view nicely animating along this transition, we add the following function to our class which gets called automatically:

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
  coordinator.animateAlongsideTransition({ context in
    self.tableView.frame = CGRectMake(0, 0, size.width, size.height)
  }, completion: nil)
}

Here we simply set the size of the table view to the size of the widget, which is the first parameter.

Of course we still need to call our update method as well as reloadData on our tableView. So we add these two calls to our success closure when we load the items from the feed

success: { feedItems in
  self.items = feedItems as? [RSSItem]
  
  self.tableView.reloadData()
  self.updatePreferredContentSize()

  completionHandler(.NewData)
},

Let's run our widget:

Screen Shot 2014-09-09 at 13.12.50

It works, but we can make it look better. Table views by default have a white background color and black text color and that's no different within a Today widget. We'd like to match the style with the standard iOS Today widget so we give the table view a clear background and make the text of the labels white. Unfortunately that does make our labels practically invisible since the storyboard editor in Xcode will still show a white background for views that have a clear background color.

If we run again, we get a much better looking result:

Screen Shot 2014-09-09 at 13.20.05

Open post in Safari

To open a Blog post in Safari when tapping on an item we need to implement the tableView:didSelectRowAtIndexPath: function. In a normal app we would then use the openURL: method of UIApplication. But that's not available within a Today extension. Instead we need to use the openURL:completionHandler: method of NSExtensionContext. We can retrieve this context through the extensionContext property of our View Controller.

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
  if let item = items?[indexPath.row] {
    if let context = extensionContext {
      context.openURL(item.link, completionHandler: nil)
    }
  }
}
More and Less buttons

Right now our widget takes up a bit too much space within the notification center. So let's change this by showing only 3 items by default and 6 items maximum. Toggling between the default and expanded state can be done with a button that we'll add to the footer of the table view. When the user closes and opens the notification center, we want to show it in the same state as it was before so we need to remember the expand state. We can use the NSUserDefaults for this. Using a computed property to read and write from the user defaults is a nice way to write this:

let userDefaults = NSUserDefaults.standardUserDefaults()

var expanded : Bool {
  get {
    return userDefaults.boolForKey("expanded")
  }
  set (newExpanded) {
    userDefaults.setBool(newExpanded, forKey: "expanded")
    userDefaults.synchronize()
  }
}

This allows us to use it just like any other property without noticing it gets stored in the user defaults. We'll also add variables for our button and number of default and maximum rows:

let expandButton = UIButton()

let defaultNumRows = 3
let maxNumberOfRows = 6

Based on the current value of the expanded property we'll determine the number of rows that our table view should have. Of course it should never display more than the actual items we have so we also take that into account and change our function into the following:

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  if let items = items {
    return min(items.count, expanded ? maxNumberOfRows : defaultNumRows)
  }
  return 0
}

Then the code to make our button work:

override func viewDidLoad() {
  super.viewDidLoad()

  updateExpandButtonTitle()
  expandButton.addTarget(self, action: "toggleExpand", forControlEvents: .TouchUpInside)
  tableView.sectionFooterHeight = 44
}

override func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
  return expandButton
}

Depending on the current value of our expanded property we wil show either "Show less" or "Show more" as button title.

func updateExpandButtonTitle() {
  expandButton.setTitle(expanded ? "Show less" : "Show more", forState: .Normal)
}

When we tap the button, we'll invert the expanded property, update the button title and preferred content size and reload the table view data.

func toggleExpand() {
  expanded = !expanded
  updateExpandButtonTitle()
  updatePreferredContentSize()
  tableView.reloadData()
}

And as a result we can now toggle the number of rows we want to see.

Screen Shot 2014-09-13 at 18.53.39Screen Shot 2014-09-13 at 18.53.43

Caching

At this moment, each time we open the widget, we first get an empty list and then once the feed is loaded, the items are displayed. To improve this, we can cache the retrieved items and display those once the widget is opened before we load the items from the feed. The TMCache library makes this possible with little effort. We can add it to our Pods file and bridging header the same way we did for the BlockRSSParser library.

Also here, a computed property works nice for caching the items and hide the actual implementation:

var cachedItems : [RSSItem]? {
  get {
    return TMCache.sharedCache().objectForKey("feed") as? [RSSItem]
  }
  set (newItems) {
    TMCache.sharedCache().setObject(newItems, forKey: "feed")
  }
}

Since the RSSItem class of the BlockRSSParser library conforms to the NSCoding protocol, we can use them directly with TMCache. When we retrieve the items from the cache for the first time, we'll get nil since the cache is empty. Therefore cachedItems needs to be an optional as well as the downcast and therefore we need to use the as? operator.

We can now update the cache once the items are loaded simply by assigning a value to the property. So in our success closure we add the following:

self.cachedItems = self.items

And then to load the cached items, we add two more lines to the end of viewDidLoad:

items = cachedItems
updatePreferredContentSize()

And we're done. Now each time the widget is opened it will first display the cached items.

There is one last thing we can do to improve our widget. As mentioned earlier, the completionHandler of widgetPerformUpdateWithCompletionHandler can also be called with NCUpdateResult.NoData. Now that we have the items that we loaded previously we can compare newly loaded items with the old and use NoData in case they haven't changed. Here is our final implementation of the success closure:

success: { feedItems in
  if self.items == nil || self.items! != feedItems {
    self.items = feedItems as? [RSSItem]
    self.tableView.reloadData()
    self.updatePreferredContentSize()
    self.cachedItems = self.items
    completionHandler(.NewData)
  } else {
    completionHandler(.NoData)
  }
},

And since it's Swift, we can simply use the != operator to see if the arrays have unequal content.

Source code on GitHub

As mentioned in the beginning of this post, the source code of the project is available on GitHub with some minor changes that are not essential to this blog post. Of course pull requests are always welcome. Also let me know in the comments below if you'd wish to see this widget released on the App Store.

Categories: Companies

React In Modern Web Applications: Part 2

Xebia Blog - Fri, 09/12/2014 - 23:32

As mentioned in part 1 of this series, React is an excellent Javascript library for writing highly dynamic client-side components. However, React is not meant to be a complete MVC framework. Its strength is the View part of the Model-View-Controller pattern. AngularJS is one of the best known and most powerful Javascript MVC frameworks. One of the goals of the course was to show how to integrate React with AngularJS.

Integrating React with AngularJS

Developers can create reusable components in AngularJS by using directives. Directives are very powerful but complex, and the code quickly tends to becomes messy and hard to maintain. Therefore, replacing the directive content in your AngularJS application with React components is an excellent use-case for React. In the course, we created a Timesheet component in React. To use it with AngularJS, create a directive that loads the WeekEntryComponent:

angular.module('timesheet')
    .directive('weekEntry', function () {
        return {
            restrict: 'A',
            link: function (scope, element) {
                React.renderComponent(new WeekEntryComponent({
                                             scope.companies, 
                                             scope.model}), element.find('#weekEntry')[0]);
            }
        };
    });

as you can see, a simple bit of code. Since this is AngularJS code, I prefer not to use JSX, and write the React specific code in plain Javascript. However, if you prefer you could use JSX syntax (do not forget to add the directive at the top of the file!). We are basically creating a component and rendering it on the element with id weekentry. We pass two values from the directive scope to the WeekEntryComponent as properties. The component will render based on the values passed in.

Reacting to changes in AngularJS

However, the code as shown above has one fatal flaw: the component will not re-render when the companies or model values change in the scope of the directive. The reason is simple: React does not know these values are dynamic, and the component gets rendered once when the directive is initialised. React re-renders a component in only two situations:

  • If the value of a property changes: this allows parent components to force re-rendering of child components
  • If the state object of a component changes: a component can create a state object and modify it

State should be kept to a minimum, and preferably be located in only one component. Most components should be stateless. This makes for simpler, easier to maintain code.

To make the interaction between AngularJS and React dynamic, the WeekEntryComponent must be re-rendered explicitly by AngularJS whenever a value changes in the scope. AngularJS provides the watch function for this:

angular.module('timesheet')
  .directive('weekEntry', function () {
    return {
      restrict: 'A',
      link: function (scope, element) {
        scope.$watchCollection('[clients, model]', function (newData) {
          if (newData[0] !== undefined && newData[1] !== undefined) {
            React.renderComponent(new WeekEntryComponent({
                rows: newData[1].companies,
                clients: newData[0]
              }
            ), element.find('#weekEntry')[0]);
          }
        });
      }
    };
  });

In this code, AngularJS watches two values in the scope, clients and model, and when one of the values is changed by an user action the function gets called, re-rendering the React component only when both values are defined. If most of the scope is needed from AngularJS, it is better to pass in the complete scope as property, and put a watch on the scope itself. Remember, React is very smart about re-rendering to the browser. Only if a change in the scope properties leads to a real change in the DOM will the browser be updated!

Accessing AngularJS code from React

When your component needs to use functionality defined in AngularJS you need to use a function callback. For example, in our code, saving the timesheet is handled by AngularJS, while the save button is managed by React. We solved this by creating a saveTimesheet function, and adding it to the scope of directive. In the WeekEntryComponent we added a new property: saveMethod:

angular.module('timesheet')
  .directive('weekEntry', function () {
    return {
      restrict: 'A',
      link: function (scope, element) {
        scope.$watchCollection('[clients, model]', function (newData) {
          if (newData[0] !== undefined && newData[1] !== undefined) {
            React.renderComponent(WeekEntryComponent({
              rows: newData[1].companies,
              clients: newData[0],
              saveMethod: scope.saveTimesheet
            }), element.find('#weekEntry')[0]);
          }
        });
      }
    };
  });

Since this function is not going to be changed it does not need to be watched. Whenever the save button in the TimeSheetComponent is clicked, the saveTimesheet function is called and the new state of the timesheet saved.

What's next

In the next part we will look at how to deal with state in your components and how to avoid passing callbacks through your entire component hierarchy when changing state

Categories: Companies

Recent Tracker Outages and Planned Stability Improvements

Pivotal Tracker Blog - Thu, 09/11/2014 - 18:01

Pivotal Tracker is a critical tool for thousands of teams, and providing a stable, reliable service is vitally important for us. Uptime is typically in the proverbial “three nines” (99.95% for the first half of the year), but in the last few weeks we’ve experienced a number of unexpected outages. The worst of which was yesterday, lasting almost two hours.

This was disruptive to many of you, and we’d like to apologize.

Outage Details

These recent outages followed a similar pattern, and as is typical with catastrophic events, they were due to a number of factors conspiring together.

The triggering event was that requests to our externally hosted WordPress site started timing out or getting blocked (for different reasons), causing a backup at our load balancers. These shared load balancers operate with a high number of open connections, due to thousands of polling requests per second from the Tracker web application, and these backups pushed them over a certain threshold and into bad state.

Unfortunately, the new beta version of the Tracker web application, which the majority of our users are now on, did not handle server outages well, and clients on the beta continued to send a barrage of requests to the load balancers, making it difficult for them to recover.

Steps We’re Taking

Here’s what we’re doing to make sure this never happens again. Some of these things were already in progress, but are being accelerated after yesterday’s outage.

First, we’ve made sure that the beta web clients immediately back off their polling requests when a server outage is detected, making it easier for overwhelmed load balancers to recover. We’ve also temporarily increased the interval between polling requests. Both of these changes were made yesterday afternoon.

Over the next few weeks, we are:

  • Moving from shared load balancers to multiple pairs of dedicated load balancers, giving us more resources including a larger pool of available connections;
  • Moving the externally hosted WordPress site (for our marketing pages) to our application production environment for more stability and control;
  • Segregating polling traffic from other types of requests;
  • Making our polling architecture more robust, which will also improve the user experience around going off-line;
  • Analyzing the entire production environment for other opportunities to improve stability and performance.

On a longer term front, we’re starting work to transition Tracker’s polling architecture (for keeping clients up to date with project changes) to server “push”, most likely via server side events, with fall-back to polling only when necessary. Not only will this result in less chatty (and more stable) overall architecture, but changes to stories will propagate instantly, and it will open the door to a new class of “live” features in Tracker.

Stay tuned for updates on progress, and again, please accept our apologies for these recent outages. Please follow us on Twitter for all the latest updates, and to monitor Tracker system status, visit our status page.

The post Recent Tracker Outages and Planned Stability Improvements appeared first on Pivotal Tracker.

Categories: Companies

Agile Volunteering, Rally Style

Rally Agile Blog - Thu, 09/11/2014 - 17:00

Rally Onboarding Bootcamp: Class of June 2014

“Rally truly practices what it preaches. Volunteering at There With Care touched my heart and made me proud that the company I work for is helping such a wonderful organization. It was amazing how we pulled together as a team and incorporated our Agile training from earlier in the day into our give-back project.” — Terri Barrowcliff, Customer Relationship Manager, Rally Onboarding Bootcamp, June 2014

During my first year at Rally, we’ve experienced exciting growth as a company. When I started in August 2013, we had about 400 people worldwide. Today, we’re over 500 and still growing. With so many people joining the company, we’re continuously refining our onboarding process — adapting it to focus on what newcomers really need to know to succeed at Rally, and introducing a strong dose of company culture. Each month, new employees from around the globe come to our Boulder headquarters to experience Onboarding Bootcamp, Rally style.

Giving back to the communities in which we live and work is among the values on which Rally was founded and holds dear (see 1%: Small Percentage, BIG Impact). Another of our core values, as you might expect, is to Live Agile. So we challenged ourselves to combine the two: create an impactful community service activity that instills the importance of giving back our time and talents that’s also a hands-on learning opportunity in Agile practices. 

I reached out to Jodee Spalding, Volunteer Director at There With Care, a Boulder-based nonprofit organization that provides fundamental support services to families and children facing critical illness. I knew that There With Care relies heavily on volunteers to deliver its services and found a willing partner to customize a program for Rally. With Jodee’s help we quickly identified an important need that Rally could fulfill.

“Easy Meal Care Bags are essential to the parents and caregivers of children being treated in the hospital. Instead of leaving for meals, loved ones can stay at the child’s bedside to provide comfort and support, and ensure they don’t miss an opportunity to speak to the child’s doctor. Now that Rally is sending volunteers once a month to create the bags — and funding the cost — we are able to replenish them as needed, and the families are so grateful.” — Jodee Spalding, There With Care

On their first day of Rally Bootcamp, new employees spend two hours with our Agile coaches learning about Agile concepts, methodology, and practices. Later that afternoon at There With Care, we ask the new hires to practice some of those concepts — such as self-organizing teams, collaboration, and inspect/adapt — when assembling the Easy Meal Care Bags. We provide the product requirements and let the team decide how to get the job done, with the following guidance:

  • Take time to plan the work and organize as a team
  • Focus on quality and process, more than on quantity and speed
  • Limit work in progress (WiP) and watch out for bottlenecks
  • Respond to change over following a plan
  • Consult the Product Owner (Jodee) as much as needed
  • End with a retrospective — what did we learn and what could we do better next time?

Rally Bootcamp participants conduct a midpoint review while assembling Easy Meal Care Bags.

Since February, 134 employees have volunteered at There With Care, contributing a total of 201 hours and creating 425 Easy Meal Care Bags weighing in at 3,188 pounds of food and drinks — lovingly delivered to parents stationed at the bedsides of their critically ill children. A grant from the Rally For Impact Foundation covers the cost of the bag contents, which has totaled nearly $5,000 since the partnership started just nine months ago.

“Just as meaningful as the grant is Rally’s donation of more than 200 volunteer hours from new groups of big-hearted Rallyers lending their compassion each month. In appreciation, we’ve honored Rally with our Inspiration Award, presented to individuals and community partners that have contributed outstanding service to There With Care’s mission.” — Jodee Spalding, There With Care

Geri Mitchell-Brown
Categories: Companies