antiagile

Agility insights

I’ve been talking recently lots with people from different companies to understand how they are moving towards agility. Many of them are saying – yes we are fully doing Agile right now. When I’m hearing this “magic” sentence I always ask – please tell me more… tell me what do you mean by “doing Agile”, how it works for you…

So here is a summary of Agile perspective that is evolving inside those companies:

  • Agile equals iterative delivery,
  • Scrum Master is a report manager,
  • Scrum Master is responsible for assigning tasks to developer,
  • Scrum Master acts as project manager,
  • Product Owner assigns stories to sprints,
  • Two roles exists inside a team: Project Manager & Product Owner,
  • Agile ceremonies make company agile,
  • Developer is mostly interested in his tasks,
  • Agile means writing requirement as User Story.

Does it sound familiar to you? Is it one of the companies that you know? Those are typical Agile Anti-patterns in my opinions and in fact most of them are against an agile mindset. Understanding how companies imagine agility helps me realise how much work still need to be done to create the right meaning of it. After fixing it inside your working environment you could start to create a people-oriented organisation based on learnings and transparency.

IMG_20160424_193418782_HDR

London Lean Kanban Days – key takeways

There was London Lean Kanban Days conference last week. Thanks to HolidayCheck I had a pleasure to participate in this event. As well as being excited by announced speakers (Pawel Brodzinski, Tobbe Gyllebring, Gitte Klitgaard) I was really looking to meet British Lean community to get a different perspective. In this post, I would like to share with you key takeaways from this conference.

  • Visualize a problem rather solve it – creating an awareness is often enough, then let people fix it – as a coach you don’t have to do everything by your own.
  • Lean = LeaRn – we sometimes forget about the main concept of lean which is continuous learning while focusing on other Lean principles like establishing flow, implementing pull approach or defining value from a customer perspective. Take your time for reflection, analyze what you achieved and learned.
  • Acknowledge yourself – you need to take advantage of the imposter syndrome by things like realizing that your experience is unique, fear indicates growth and keeping pushing your boundaries, improving where you have a passion.
  • Traditional project management is much closer to Agile mindset nowadays. The most needed skill for a project manager is leadership and an organization should aim to be adaptable.
  • Extreme self-organization at the company level is doable – it takes a time, it is not one-day shift and probably part of people will decide to leave your company.
  • While doing a change you need to have someone responsible for delivering value, and facilitating the risk assessment, you need to focus on organizational goals instead of local targets.

Android Runtime Permissions

Android Runtime Permissions

Permissions are used to restrict access to sensitive resources, data and hardware features. Android 6.0 Marshmallow (SDK level 23) introduced the concept of Runtime Permissions, changing many aspects of managing them in Android. The change is aimed to greatly improve user experience and it seems the Android Team did just that. On the other hand, developers need to incorporate those changes into their apps, which might not look that easy at first glance.

Traditional permission model

  • application install requires all of the permissions to be accepted by the user
  • the only way to revoke them is to uninstall application (all or nothing approach)
  • new permissions prevent apps from auto-updating, they need additional review by the user1
  • required permissions are declared in Android Manifest and application can assume, that if it is installed, it has all of them granted

New runtime permission model

Now, every permission falls into one of three protection levels:

  • normal applications get them by default at the time of installation (for instance Internet connectivity)
  • dangerous must be granted explicitly by the user
  • signature custom permissions based on signing certificates that should match in order to request them, typically used by applications by the same developer in order to exchange some private, proprietary data

In addition to protection levels, new concept of permission groups has been introduced:

  • few separate permissions (like we are used to) might be grouped together into one group
  • user implicitly grants us all permissions from the group, that requested permission belongs to
  • if we ask for more than one permission in a group, they are granted/denied automatically based on users decision regarding the group

Dont assume that if you possess a permission from particular group, you also have all the other permissions from that group always ask for specific ones, because current behavior might change in the future.

What all of that means for your users, is they can just install any given app from the Play Store and start using it right away (no questions during installation asked). Permissions falling into normal protection level are granted by default, and those should be enough for typical app to function, at least at the beginning. The process of asking for permissions is pushed back to the last possible moment the moment that user wants to perform an action requiring dangerous permission, for example action of taking a photo would be briefly interrupted by a system dialog with permission request. Finally, user can grant or revoke2 any permission at any time from system settings, without uninstalling app.

App permissions can be fine-tuned separately app by app

When user revokes permissions, our applications process gets killed.

All is fine for the user, but life of an ordinary Android developer has just got slightly more complicated. Were now required to take extra care and prepare for few scenarios, making sure that we:

  • declare required permissions in Android Manifest as usual
  • check on-the-fly, that we are actually granted permissions required to perform given actions
  • disable certain UI controls or indicate in other ways that application could perform those actions, if it had those permissions
  • are prepared for permission revocation at any given time
  • make a clear distinction between permissions vital to your application and optional ones
  • show disclaimers and reasoning behind requests up-front or in context as they are needed

Asking for Runtime Permissions

All features are backported to both Support Library v4 and v13.

1. Opt-in for Runtime Permissions

In order to opt-in for Runtime Permissions, you need to build your application with Target SDK 23 or higher. If youre using Gradle (which you should be doing), make sure its set in build.gradle:

compileSdkVersion 23
targetSdkVersion 23

2. Declare permissions in AndroidManifest

No changes here, declare needed permissions in AndroidManifest.xml as usual:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="io.github.adamjodlowski.playground">

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

    <application>...</application>

</manifest>

3. Make sure to check if permissions have been granted and ask for them if necessary

System window pops up to get user's approval

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{ Manifest.permission.ACCESS_FINE_LOCATION }, 123);
        } else {
            Log.d("PLAYGROUND", "Permission was already granted");
        }
    }

    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        if (requestCode == 123) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Log.d("PLAYGROUND", "Permission has been just granted");
            } else {
                Log.d("PLAYGROUND", "Permission has been denied or request cancelled");
            }
        }
    }
}

As you can see, we use few new methods from Runtime Permissions API. Those are fairly straightforward, but there are few things to note:

  • you can request many permissions, passing an array to ActivityCompat#requestPermissions() method
  • you need to make sure the code is prepared for brief interruption introduced by the request, as well as correctly receive result in onRequestPermissionsResult(), the mechanism is the same as onActivityResult() that you should be already familiar with
  • you can check approval/denial on single permission level notice that response contains requested permissions and separate results for them

You are required to check permissions status every time you might need them, dont assume that you got permission once and its available forever.

Additional considerations

I suppose youve noticed that after first denial user is given the option not to bug them anymore with our request. This is virtually our last chance to explain them reasoning behind the request. In order to do that gracefully, API contains method that returns true, if we previously requested particular permission, but user denied the request:

if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
	// the request has been denied previously, show explanation why you need this, then request permission again!
} else {
	// ask without explanations
}

Please note, this method returns false if user already checked Never ask again checkbox.

Asking second time, user can permanently dismiss this dialog for our app

Theres another feature introduced in SDK 23. You can ask for permissions only if the platform supports runtime permissions, so you can optionally provide new features, but dont request new permissions from users on older platforms upon auto-update of existing installed app. All we need is declaration in Android Manifest:

<uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION"/>

This permission would behave as runtime permission and request for it would appear only on Android 6.0 and newer. For users on older platforms, nothing changes.

Few points to keep in mind

  • apps compiled with Target SDK < 23 are treated as usual
  • many basic permissions are granted by default
  • you still need to declare them in the Manifest
  • you must check every time you need them (Activity#onCreate() is sufficient)

Protip: Android Studio parses annotations and warns you if you try to make an API call but dont request needed permissions.


  1. That leads to developers requesting more permissions that they really need, in order to prevent already installed applications from bugging user again when new app features arrive. This is bad practice. ©
  2. This doesnt mean legacy apps are going to crash like crazy after you revoke permissions, throwing Exceptions all over the place. What really happens is, on Android 23+, API calls that had been restricted would return empty data sets or default values, as if there were no data available. ©

Content Freaks & Mob programming adventure

cf-logo-v3In Holidaycheck’s Poznań IT department we work in teams that consist of frontend & backend developers. We pay a lot of attention to knowledge sharing within a team in order to have a common understanding of our architecture and why we’ve chosen one solution over another . For a long time we’ve had well balanced sprints, meaning that we had a few frontend and backend tasks in each sprint. Recently however, due to our business strategy and migration process of our platform, more and more tasks have became frontend focused.

We didn’t want our backend devs to get bored! We wanted to use the potential of the whole team, which meant involving backend devs in frontend tasks. We started looking for solutions that can be helpful in learning new technology stack. One of the things that came to mind was pair programing, which is a great idea for sharing knowledge, but… our scrum master proposed to try MOB programming… We thought: “Why not!? We are an agile team, so why not to try something different and learn !?” 😉

MOB programming in a nutshell, is a scaled up version of Pair programming, with more than two developers. In our case it was four: two frontend and two backend guys. We’ve prepared one of our conference rooms  to be the headquarters of our MOB programming session. We used a big TV as an external monitor – just to feel more comfortable and not to squeeze four people in front of a tiny laptop screen for hours 🙂  Second laptop was used for research, to not disturb the main flow of coding.

mob2

We’ve picked one frontend story, which was not very complex, but great for learning the basics. At the beginning of our MOB  session, backend part of our team had a feeling that the story is just a piece of cake … but it wasn’t. Backend guys haven’t had any experience with our current frontend stack and didn’t have a clue about how complex and tricky the story  might be. After we’ve discussed how we would implement the story, we were ready to code! Development process looked a little bit different from pair programming. One of the developers was a “driver”, sat in front of the laptop and owned the keyboard. He was coding what was discussed and agreed on by everyone.   The session revolved around frontend guys suggesting how the story should be done, which was then being discussed by everyone. From time to time, we also had a discussion regarding more general programming ideas like testing approach etc. The MOB session was divided into short iterations  (15-20 min) in which each of us became the driver, which allowed previous driver to focus on research and discussion.

Good parts:

  • sharing knowledge
  • new angle of looking at solutions that we are using on daily basis
  • rise  of team spirit and collaboration
  • backend guys started to like coding on frontend stack

Other observations:

  • the session slowed down the progress of product features in the current sprint, but that was expected and accounted for, as we believe it will enable us to be faster in future
  • frontend guys would love to do a similar session with a backend story 🙂
  • a whole day is too long to develop in that style
  • MOB approach shouldn’t be abused!  🙂

In summary, although we had certain reservations before we started, MOB programming turned out to be a really great experience for us! We think we will be using it   in future, as a mean  of fast learning and knowledge sharing… Maybe frontend guys will learn & love Scala? 🙂   Time will tell… 🙂

Journey to T-Shape team

t-shapeThere is a trend on the IT market to be software developer who has expertise in one specific technology (vertical line in “T”) and knows others at levels that don’t stop him from understanding a full code (horizontal line in “T”). This whole idea seems to help building cross-functional team, one of core thing in Agile world.

Currently the team that I’m working with has decided to try to become T-Shape one. There have been a few discussions how to tackle it, what should be assumptions and how we can manage dependencies. We have used brainstorming session to create a plan that all of us would support. Here is our approach:

  1. Create skill matrix to get knowledge what kind of expertise team has.
  2. Identify skills that should be strengthened.
  3. Verify in which directions team member would like to develop.
  4. Each team member proposes plan of skill’s development with clearly stated goals.
  5. Scrum Master facilitates and challenges progress on skills’ learning plan on monthly basis.

On top of this, the whole team has agreed that during transformation into T-Shape developer we still need to follow principles mentioned as below:

  • Each team member has main focus on core skill/-s.
  • We will plan how to grow individual horizontal skills during sprint planning so we could forecast more accurate sprint deliverable.
  • Each team member is responsible for his/her skill’s development.
  • Each team member seeks actively new ways of skills’ learning.

As you can see the team has decided to move closer to be cross-functional team in structured way, doing it step by step. Such approach gives them a chance to adjust it if needed and to validate their progress (see points 4. & 5.). Additionally it should help minimizing an influence on sprint deliverables. Keep finger crossed!

If you have any experience in creating T-Shape team let me know. I’m curious to find out how you have transitioned to it and I’m open for your advice!

 

Marathon Maven plugin from HolidayCheck

At HolidayCheck we are using both Docker and Apache Mesos with Mesosphere’s Marathon. Therefore for our development teams creating services using Maven we wanted to set up easy to use configurations bound to standard Maven lifecycle phases.

Starting with Docker Maven plugin

As wiring a Java/Scala project for Docker is possible by multiple existing plugins, we have chosen Spotify’s Docker Maven plugin, as it best suited our needs, was easy to integrate and allowed to use Git commit hashes (aside from standard artifact versions) in Docker image names for uniqueness.

Marathon Maven plugin usage example

You can have a look at the plugin on the GitHub:
https://github.com/holidaycheck/marathon-maven-plugin
or even start using it already in your project:

<plugin>
     <groupId>com.holidaycheck</groupId>
     <artifactId>marathon-maven-plugin</artifactId>
     <version>0.0.1</version>
     <configuration>
         <image>${docker-image-prefix}/${project.build.finalName}:${project.version}</image>
         <marathonHost>${marathon.protocol}://${marathon.host}:${marathon.port}</marathonHost>
     </configuration>
     <executions>
         <execution>
             <id>processConfig</id>
             <phase>install</phase>
             <goals>
                 <goal>processConfig</goal>
             </goals>
         </execution>
         <execution>
             <id>deploy</id>
             <phase>deploy</phase>
             <goals>
                 <goal>deploy</goal>
             </goals>
         </execution>
     </executions>
</plugin>

To interact with Marathon the plugin uses Marathon Java API client. In the processConfig goal the plugin takes marathon.json file currently located by default in root project directory, which might
look like the one here:

{
  "id": "/my-service-1",
  "container": {
    "type": "DOCKER",
    "docker": {
      "image": "docker-registry.your.org/my-team/my-service",
      "network": "BRIDGE",
      "portMappings": [
        {"containerPort": 7070},
        {"containerPort": 7071}
      ]
    }
  },
  "env": {
    "PATH_PREFIX": "/my-service",
    "_JAVA_OPTIONS": "-Xms64m -Xmx128m -XX:MaxPermSize=64m"
  },
  "instances": 1,
  "cpus": 0.5,
  "mem": 256,
  "healthChecks": [
    {
      "protocol": "HTTP",
      "portIndex": 0,
      "path": "/my-service/v1.0/healthcheck",
      "gracePeriodSeconds": 3,
      "intervalSeconds": 10,
      "timeoutSeconds": 10,
      "maxConsecutiveFailures": 5
    }
  ]
}

replaces container/docker/image with the value provided to the plugin and evaluated taking into account all used variables e.g.: docker-registry.your.org/my-team/my-service-1.0.
The result is put into project’s target directory by default. Then it’s being picked up by the deploy goal and submitted to Marathon’s API endpoint with some minor handling of a situation whether the app already exists or not in the cluster.

Docker and Marathon plugins join forces

As mentioned earlier the Marathon plugin goes well with the Docker plugin, mostly due to the fact that we might bind those two plugins together and hook them nicely to proper Maven lifecycle phases and (what is very important in our scenario) to use Git commit hash as the Docker image name detected previously by the Docker plugin to be used in Marathon plugin’ configuration:

<plugin>
    <groupId>com.spotify</groupId>
    <artifactId>docker-maven-plugin</artifactId>
    <version>0.2.6</version>
    <configuration>
        <imageName>${docker-image-prefix}/${project.build.finalName}:${project.version}-${gitShortCommitId}</imageName>
    </configuration>
    <executions>
        <execution>
            <id>build</id>
            <phase>install</phase>
            <goals>
                <goal>build</goal>
            </goals>
            <configuration>
                <maintainer>HolidayCheck</maintainer>
                <baseImage>${docker-registry}/lightweight/oracle-java-7-debian</baseImage>
                <cmd>java -jar /${project.name}.jar</cmd>
                <exposes>
                    <expose>7070</expose>
                </exposes>
                <resources>
                    <resource>
                        <targetPath>/</targetPath>
                        <directory>${project.build.directory}</directory>
                        <include>${project.build.finalName}.jar</include>
                    </resource>
                </resources>
            </configuration>
        </execution>
        <execution>
            <id>push</id>
            <phase>deploy</phase>
            <goals>
                <goal>push</goal>
            </goals>
        </execution>
    </executions>
</plugin>
<plugin>
    <groupId>com.holidaycheck</groupId>
    <artifactId>marathon-maven-plugin</artifactId>
    <version>0.0.1</version>
    <configuration>
        <image>${docker-image-prefix}/${project.build.finalName}:${project.version}-${gitShortCommitId}</image>
        <marathonHost>${marathon.protocol}://${marathon.host}:${marathon.port}</marathonHost>
    </configuration>
    <executions>
        <execution>
            <id>processConfig</id>
            <phase>install</phase>
            <goals>
                <goal>processConfig</goal>
            </goals>
        </execution>
        <execution>
            <id>deploy</id>
            <phase>deploy</phase>
            <goals>
                <goal>deploy</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Now simply type:

mvn clean deploy

and you should have it deployed and running on your target environment.

Have a good time using Marathon Maven plugin! If you are willing to contribute your pull requests are welcome.

HolidayCheck craftsmen at SoCraTes Tenerife

Last week our developers Jan-Simon Wurst, Tobias Pflug, Alexander Schmidt, Robert Jacob, Robert Mißbach and Roberto Bez went to the SoCraTes Conference on Tenerife. Of course that is kind of an unusual place for a conference, but exactly that makes the difference. Beeng somewhere isolated, like in a lonely hotel near the beach, gave us a very relaxed and comfortable feeling while talking with other great people about software craftmenship and a lot of other interesting topics.

The Venue: Tenerife

After a very windy landing on Tenerife, we went to our venue, the lovely Hotel Aguamarina Golf, located not to far away from the airport. It gave us enough space for all the sessions we needed, as for example next to the pool or on the terrace.

The Hotel Aguamarina Golf

What is the craftsmanship conference about?

SoCraTes Canaries in fact is a Craftmanship retreat for open-minded craftspeople who strive to improve their craft and the software industry as a whole, organised by the local Software Cratfsmanship comunity in the Canary Island.

Tenerife-Hotel-View

It is a totally community-focused Open Space, without a predefined agenda and without any speakers known before the event starts. Proposals were presented during the event itself in the morning:

Session planing in the morning

After the proposals were presented, we had five different locations (like classic rooms with projectors, but also near the pool or on the terrace, while enjoying a great view of the atlantic sea).

20150228_101344903_iOSDiscussions

Discussion about costs of CI and CD

 

Talks & Discussions

Just to name some topics we discussed:

Jan-Simon Wurst proposed a discussion about Git Flow vs. trunk based development, trying to find out how other developer teams work and which might be the better solution. But as always – there is no perfect way, but a lot of right ones!

Robert Jacob showed us HolidayChecks continuous deployment pipeline with Mesos and Docker, facing a lot of interesting questions about that hyping topic.

Tobias Pflug let us had a deeper insight into his vim-skills, presenting some of his favorite plugins. Very cool stuff!

Roberto Bez initiated a discussion about distributed teams by sharing his experience about that and with a lot of interest in how other companies are currently facing with not co-located teams. For some it might work, for others it does not – but one outcome was clear: It is not always easy!

With two days full of interesting discussions, in the evening there was the time to enjoy a beer together as well.

To sum up, we went back home with a lot of new motivation, which we can hopefully use to become better craftsmen in our daily work!

A special thanks to Carlos Blé and all the other organizers for the great conference. We are already looking forward to visit you again in 2016!

How we do Agile Intro Workshops at HolidayCheck

legopic1

Why do we do Agile Intro Workshops

When you are situated in a web driven company with more than 200 employees in one location – plus
dozens on top in distributed offices – the need for a common basic understanding of agile product
development is at hand.
Our product development consists of +/- 8 teams – all contributing to different parts of the web platform
plus native mobile apps.
So we experience communication and alignments that go far beyond the dedicated product dev teams only – basically all departments have a smaller or bigger stake in the agile teams.
That leads us to the need to have a basic common understanding of Agile and how we live it at HolidayCheck.

For whom do we do them

The target groups are always totally mixed and come from different departments – this way we ensure that people come together and form a completely new virtual team during the workshop. After the workshops they are again released to their native teams and their well known area – able to bring in and spread the learnings immediately.

How do we do them

We set a timebox to 90mins and have a theoretical part and a practical part – a simulated sprint with the goal to build something that is ready to use in very few minutes.

The theoretical part covers basic knowledge about Agile, Scrum and Kanban:

  • The need for Agile product development
  • The roles and artifacts
  • The specific team constellation here at HolidayCheck
  • Agile Tools we use at HolidayCheck

And now comes the fun part! We use LEGO bricks to simulate a sprint with the goal to build a house, a garden and a car.
After about 45mins the audience is asked to form 1-2 agile teams themselves to do that – they are given roles they need to fulfill the best they can – even if their real role is completely different (believe me, software developers always want to build stuff instead of just telling where the team should head at).
Roles we use are Product Owner, Developers, UX Designer, Test Engineer.

legopic4

The Scrum Master role is filled by us as the moderators themselves. Also if the teams are rather small, with +/- 4 people, we only use Product Owner and Developers to keep it more simple and going forward.
We use small time boxes to simulate

  • A sprint planning session (2mins)
  • The sprint itself (5mins)
  • A sprint review (2mins)
  • A sprint retrospective (1min)
  • legopic2

The teams apply the given info instantly and also try to prioritise and deal with the limited time.
This gives them a feeling of how real teams have to focus and organise themselves.
Many people think that building a house with LEGO bricks with a whole team is super easy in 5mins – trust me: experience shows that many struggle to finish in time, while others do really great.

legopic3

What do you think? Please comment and tell us your experiences!

An Easy Way to Measure Method Calls in a Java resp. Scala Application

In the following find a description how to measure certain method calls in a Scala application even under production load.

To collect execution times for analysis e.g. for locating performance problems in existing Java™ respectively Scala applications you can use JETM. JETM is a library offering execution measurement. The overhead is little compared to Java™ Virtual Machine Profiling Interface (JVMPI) or Java™ Virtual Machine Tool Interface (JVMTI) and the related profiler extensions. Thus the risk to slow down the application in production environment is also little.

Using the programmatic approach of performance monitoring with HttpConsoleServer and JMX Support.

In maven pom.xml include the dependency

<dependency>
 <groupId>fm.void.jetm</groupId>
 <artifactId>jetm</artifactId>
 </dependency>

for the core measurement functionality and

<dependency>
  <groupId>fm.void.jetm</groupId>
  <artifactId>jetm-optional</artifactId>
</dependency>

for an output in a HttpConsole.  (For version information see e.g. http://repo1.maven.org/maven2/fm/void/jetm/)

Within a Singleton create a nested monitor ( ” true ” parameter) with default ExecutionTimer  and Aggregator by
BasicEtmConfigurator.configure(true).
Start an EtmMonitor with
val etmMonitor = EtmManager.getEtmMonitor
etmMonitor.start()

Start an HttpConsoleServer with
val server: HttpConsoleServer = new HttpConsoleServer(etmMonitor)
server.setListenPort(Config.JETMMonitoring.port)
server.start()

Config.JETMMonitoring.port: the port is configurable by using 

com.typesafe.config.ConfigFactory

for further information see https://github.com/typesafehub/config

Register an MBean for JMX Support:
val mbeanServer: MBeanServer = ManagementFactory.getPlatformMBeanServer

if (mbeanServer != null) {

  val objectName = new ObjectName("etm:service=PerformanceMonitor")
  // register EtmMonitor using EtmMonitorMBean
  try {
    mbeanServer.registerMBean(new EtmMonitorMBean(etmMonitor, "com.holidaycheck.mpg"), objectName)
  } catch ...
}

Keep in mind that you have to take care of stopping the measuring e.g. on shutdown hook.

Mix in the measure call by a trait e.g. named JETM that owns a reference to the monitor ( private val monitor = EtmManager.getEtmMonitor() ):

def measure[T](name: String)(op: => T): T = {
  if (!JETM.monitor.isCollecting()) return op

  val point = JETM.monitor.createPoint(jetmPrefix + name)
  try {
    op
  } finally {
    point.collect()
  }
}

(jetmPrefix is the canonical name of the class that mixes in the trait).

Within the class e.g. OfferMetaDataMap that contains the call to be measured use

class OfferMetaDataMap(...) extends ... with JETM {

  def aMethodCallToMeasure = {

    measure("Get") {
      /** basic method body */
    }

}

“Get” is the flag of the measured method. In HttpConsole this will occur like

|-----------------------------------------------------------------|---|---------|--------|--------|---------|
| Measurement Point | # | Average | Min | Max | Total |
|-----------------------------------------------------------------|---|---------|--------|--------|---------|
| com.holidaycheck.mpg.service.actors.cache.OfferMetaDataMap#Get | 4 | 3.556 | 1.029 | 6.075 | 14.224 |

The measured data is accessible via JMX or via http://[application’s url]:[configuredPort]/index.

 

For further information see  http://jetm.void.fm/doc.html

for instance about persistent aggregation see http://jetm.void.fm/howto/aggregation_persistence.html

Continuous Improvement

Continuous Improvement Culture in HolidayCheck

In this blog post we will explain how HolidayCheck is creating a continuous improvement culture across our IT and Product Development departments.

A lot of companies talk about this topic but few of them actually share it with the rest of the world. This is where HolidayCheck wants to be different. We want to share our experiences with all of you in order to help you to get better on your Agile Implementation. So lets start from the beginning.

Some months ago I had the opportunity to be a beta reader of a fantastic book called: “Lean Change Management” written by Jason Little. This book is about Agile Change management in our companies and how can we create change in our companies in a very effective way. Highly recommendable.

In HolidayCheck we are trying one of Jason´s tools. This tool is called Experiment Board. Jason´s explanation for this term is simple; he feels the word “change” can be quite disruptive, so he calls it “experiment”.

Another reason for naming it like this its related with the fact that if you call changes, experiments you are developing an approach that accepts the fact that you cannot know everything upfront. Which is what usually happens in our companies.

The first step in order to use this tool is to create a hypothesis, after all, experiments start with a hypothesis. The hypothesis is an idea of something that we want to improve in HolidayCheck.

To help with this task (Hypothesis creation) Jason created a template:

We hypothesize by <implementing this change>

We will <solve this problem>


Which will have <these benefits>


as measured by <this measurement>

So mapping it now to HolidayCheck we can have something like this:

We hypothesize by “Fixing the team server instability

We will “Never fail a sprint because of team Server problems

Which will “Allow us to release new features every sprint

As measured by “The number of successful releases over the next 10 sprints

There are several ways to successful tackle a Hypothesis. These “ways” are called “options”. The next step is to brainstorm several different possible options that will allow us to solve the problem stated in our hypothesis.

Each option has a value and a cost associated to it, so the trick is to select the options with the biggest amount of value and with the smallest required effort/cost.

The selected options will be the ones that we will be implement in the near future. In HolidayCheck we define weekly options. This will allow us to get fast feedback about what we are doing.

With the pre selected options at our hand we can then chose what are the options that we want to implement during the next week.

When we are done with the option we must review what was achieved, we must see if our option caused the desired outcome. If this is the case then we are done and we succeed with our experiment. If not, we can create a new option with what we learnt.

In order to implement this process, we created a Kanban board to track all the changes that we are trying out in our company. Every week we come together and discuss with eachother what we did learn with this experiments and how these experiments are actually improving our company.

Continuous Improvement

At this point we are trying this approach with the Scrum Masters but the plan is to expand to the rest of the organization. I believe this is a fantastic way to improve companies.

Every Scrum Master has completely freedom to create hypothesis, generate different options and drive the whole improvement experiment.

My vision as Agile Coach is to create an environment where these boards are spread in different parts of the company and everyone in the whole company can pick up different topics to improve.

Can you imagine a company that provides a framework for every single employee to implement daily improvements allowing him or her to create a culture of continuous improvement?

I can, this company is called HolidayCheck.

I am an Agile Coach in HolidayCheck, and I am preparing something great for you: “Agile Retrospectives Program” this program will help you to become better and better on your continuous improvement effort.

 

TechBlog