[presentation][polish] TDD as the way to Scala enlightenment

Posted by Ktoso under coding, polish (1 Respond)

Yesterday I was presenting at the local Student IT Festival together with a friend – Tomasz Borek. We’re both quite active community people as well as TDD fans thus when I was asked to present at SFI again this year – an idea came to mind. Let’s teach Tom Scala, guiding him via writing tests.

The target audience was fresh students who have yet to learn the ways of TDD (“be enlightened” ;-)), so while the things we cover in this presentation are pretty basic for those of us hacking in the industry since some years – I believe it’s tremendously useful for people to get into “real world programming”.

The presentation is already online (although in polish):

And there’s also an video recoding of the talk online already. The SFI team will probably upload their recording soon enough – which should be in higher quality than this ‘homemade’ one ;-)

[SFI 2013] TDD drogą do oświecenia w Scali – Konrad Malawski, Tomasz Borek from Polish Java User Group on Vimeo.

Tags: , , , , , , ,

Scala 2.10 – Macros hands on with “method alias”

Posted by Ktoso under coding, english, scala (No Respond)

Where?

Last week I was presenting at JFokus (cool conference, give it a try), a really nice JVM-focused conference. Obviously I love the conference I co-organise with fellow JUG members Geecon, too but it’s always fantastic to be a participant/speaker rather than the organiser once in a while – then you actually can enjoy the talks and not run around arranging everything… :-)

After the last day of the conference there was a Stockholm Scala User group meetup which I’ve obviously had to go to :-) With a beer in hand we jokingly invented a @alias annotation that would allow you to setup aliases for symbolic methods. An example would be akka’s (scala api) that delegates to tell (java api). While I had nothing to do waiting for the plane to arrive at the airport, I hacked up a proof of concept macro that does this.

As a heads up, all the code is on github: https://github.com/ktoso/scala-macro-method-alias

What?

I came up with two syntaxes, the first one being more scala-like:

And another one, wich looks more java-like (due to the annotation ;-)), and we’ll in the joke we said it should be an annotation:

Also it has been a great occasion to try out how implementing macros actually feels – and I gotta say, we’re not in lisp heaven here, but it’s pretty ok once you get a feel for it. Static typing for the win I’d say. Also, in 2.11 we’ll probably get a “quasiquoting string interpolator”, which would make creating Trees even easier.

In this post we’ll look at how implementing a macro in Scala 2.10 looks like. We’ll just cover the 1st syntax mentioned here (1st image).

How?

Let’s start by looking at the code then, shall we? On the call site we don’t have much to do. We just import the macro, and call it with the method (partially applied). The macro will then look at this method’s signature and delegate all params to it.

Very well… Let’s move on to the implementation. It has to be an separately compilable object. The compiler will compile it, and call the macros implementation while it’s compiling the class in which our call site is. In this aliasFor method, we take the partially applied call, and “invoke” the macro (notice the macro keyword).

Now it’ll get a bit more interesting. Let’s start with looking at line 1 – the macro’s def .
It’s closely related to the invocation of the macro, see the delegate parameter here? It must be named the same way as the delegate parameter in aliasFor. If it isn’t or the signature here has more/less parameters than the signature of aliasFor – you’ll get a compile error, informing you that those must match.

Still in the signature, let’s look at c: Context, where’d that come from? You probably know – it’s the AST of our “surroundings”. You can call c.enclosingMethod or c.enclosingClass to get Tree‘s back from it. Also, it contains c.universe which may be thought of like “THE Scala entry point to reflection-land”, but since we’re still in compile-time, we get a compile-time universe. Using it we can create new AST nodes, or inspect anything that’s reachable from our code. It’s a big topic to wrap your head around, so it’s best to see the docs about it.

Next we’ll use this c to obtain what the method name of the one calling us is, and we can parse delegate to obtain the name of the method we want to delegate to. It will actually have the type information associated with it there by the way. Next we extract parameters that the delegator method has, and in the end, parse a small piece of scala code which basically is just the invocation of the target method + all the parameters it needs.

Notice that if someone would pass in more than one partially applied method into our aliasFor method, we would go into the _ case in here, and abort execution. The c.abort method causes the compiler to stop, and print out the position where it failed, along with the message we supply (there’s an example failure on the github of this project).

Lastly, having a Tree we need to convert it to an Expr – as that’s what a macro should return. Exprs are bound to an universe, but since in compile time, there’s only one universe – we can go ahead with using this simple c.Expr factory (it wouldn’t be that easy in runtime).

Sources?

That’s it… a quick overview on how writing macros looks with scala. I definitely recommend reading up about Universes and Def Macros before you head out and rewrite everything to be a macro ;-) As for the use case of this project… Well, in theory it’s useful, but the win is rather small – so I wouldn’t advertise using it everywhere it may fit ;-) It is on maven central if you’re interested to try it out though.

All usage information and sources sources (available under the Apache 2 License) are on GitHub, so check it out:
https://github.com/ktoso/scala-macro-method-alias

Tags: , , , , , , , , ,

Scala 2.10 – or, why you will love implicit value classes

Posted by Ktoso under coding, java, scala (2 Responds)

Hip hip hurray. Scala 2.10 is Final (as can be read on scala-internals) so it’s high time for another blog post celebrating all the awesomeness it’s going to bring into our daily lifes!

This time we’ll cover a pretty awesome SIP, namely: SIP-15 Value Classes. If you’re not familiar at all with the idea you should either read the SIP now, or stay with me learn why they’re so awesome, and then read the SIP. I’ll give you a paragraph of dots to think about it.

Seems you’re back! Let’s get hacking then.

So a Value Class is a smart way of encapsulating a number (for example) with a class, to make it efficient to use such simple wrapper classes. Let’s look into the “Wins” of Value Classes in two examples

Win 1: Better type checking, near-none performance costs

Before we start implementing stuff, a quick reminder about Scala’s Type Hierarchy:

skitch (5)

Focus on the Any class and it’s two children for now. On the right, we have AnyRef, which is Java’s Object, and all our classes that we write in Scala (or Java) extend it. Scala implementations have the additional layer of ScalaObject, but that’s it – this is the side of the type tree where our objects live.

With Value Classes this changes…

as we’ve become able to write classes which are on the AnyVal side of this hierarchy! This isn’t exactly a new feature for the compiler, as you can see that’s how we’ve been using java “int” which was decorated as “scala.Int” for years now. What changed in 2.10 is the fact that we can now add our own classes on this branch of the tree!

Let’s just see how Value Classes work in this blogpost, and I’ll post a more concrete example in another post, as this one is getting pretty long :-) The first question we need to answer is – “Why being on the left side here is such a big deal?”. Let’s start out with just a Meter (as in Distance) class:

Seems pretty normal. The only difference, which made it a Value Class, is the fact that we explicitly extend AnyVal. Now is a good moment to take a look at the generated bytecode (just type the example in an object Test in the REPL and the run javap -v Test to see for yourself):

Now you should probably “get” what the Value class changed… Yes, the class Meter is not used in the final bytecode! Instead we’re operating on a plain value – the Int parameter that Meter was wrapping. Thus, we didn’t add any memory overhead connected to introducing this class!

Ok, but what if this class will have some methods?

Let’s move the traveled method inside the Meter class and find out:

We’ve now moved the traveled method inside of our Meter class. What does this mean for the runtime – just an int won’t do, since we’re calling things on it… right?

As you can see – an int is plenty enough to support even method calls “on it”! The compiler is smart enough to replace all Meter.traveled calls with a static call to it’s companion object Meter$.traveled(int) which as you can see… again takes a plain int, instead of an Meter instance!

That’s pretty sweet – we the type safety of Meter at compile time, and we can use it to make our methods “feel strongly about” what is passed into them – accept only Meter, yet at runtime we don’t have ANY memory increase due to passing around big objects – we’re back to primitives!

Win 2: Implicit methods get a boost!

This “Win” could also be called “Implicits loose the runtime overhead of creating the Wrapper class each time!” or “Scala gets real Extension Methods!”.

Just a quick reminder on implicits in Scala: We can use implicit conversions to decorate some type, with another type and, seemingly, add methods to it. In Scala 2.9 we’d do it like this:

So there are two new things here in Scala 2.10, one is that we can get rid of the asAwesomeString method, which pretty much was just boilerplate to convert a String into an AwesomeString.

Implicit classes are also new in 2.10

This is done by using an implicit class (which are described in detail in SIP-13), but this is not our focus today. Just assume they generate the boilerplate called “asAwesomeString” for you, and work the same way otherwise.

What’s more interesting for us in this blog post here is that by using both features SIP-13 and SIP-15 we can construct an implicit value class. Let’s take a look at the bytecode generated by both, the implicit class as well as the implicit value class to spot the difference:

The implicit class goes first:

Most notably, take a look at the parts of the bytecode marked with ^^^^ and vvvv. The AwesomeString method (generated for us by the compiler) returned the Wrapper class here, and then on the instance of AwesomeString the .awesome_!() method gets called.Pretty normal implicits use so far. Bear in mind that this wrapper creation is done for each implicit method you call – it’s not cached, even if you chain multiple implicit calls on the same String instance that we just wrapped.

Implicit Value Class

In contrast, this is the bytecode generated for an implicit value class:

Let’s again focus on the bytecode marked with vvvv and ^^^^. This time the wrapper function is still called, but it returns the same string instance that came in (ScalaGurus – why can’t the compiler just skip this invocation and call the extension method right away?).

Then this string is passed right into the awesome_!(String) method defined on the companion object. As you see the difference here is that we pass in the unboxed value to the extension method (yeap, let’s call it this way) whereas before we would call this method on the wrapper object.

Turns out that using “plain extension methods”, via defining implicit value classes has noticeable performance benefits (small but hey, it adds up!). And if you would like to see this used somewhere else than just “some guys blog”, look no futher and check out StringOps in Scala’s sources.

More info @ ScalaWags

Since Daniel, Dick & Josh have just recenly discussed this (and other) features of Scala 2.10 I’d like to link their awesome ScalaWags podcast here. This is an exact link to the part where they discuss value classes as well as implicit classes, so feel free to grab a coffee and hear then out nerding around the Scala Collections library – something we all love to do :-) Oh and be sure to follow @TheScalaWags on twitter.

Shameless Plug: GeeCON 2013 – Call For Papers

A small shameless plug… As we’re right in the middle of preparing 2013′s “All around the JVM” GeeCON conference, I thought that bringing in even more awesome Scala people would be… even more awesome? ;-) So, if you’re interested in anything around the JVM (Scala? :-)) – why not submit your talk to our C4P?

Tags: , , , , , , ,

Use Scala’s DynamicVariable to avoid closing over a value in Akka

Posted by Ktoso under coding, english, scala (2 Responds)

Note: As Steve points out in the comments this is actually NOT SAFE (the solution with DynamicVariable). (!)

If you’ve ever read Akka’s docs about Actors or saw this blogbost about how to avoid closing over the sender in Akka you already know why you shouldn’t close over the sender value when implementing actors with futures inside them. In this post we’ll discover a nice Scala utility class we can use to solve this problem.

But first… what is the problem?

// BROKEN! DON'T DO THIS AT HOME!
  1. class Caplin extends Actor {
  2.   def recieve = {
  3.     case _ => Future { sender ! "カピバラ" } // OUCH!
  4.   }
  5. }

The above code may fail, as the variable sender (it’s actually a method) is “shared mutable state”! Why? Well, there’s one instance of Caplin, yet the sender changes each time someone sends Caplin a message right? So while the future is executing, the value of sender may have changed (as another message just came in). The above code would then end up responding to the wrong sender.

Now with having the problem defined, let’s see how we can solve it. The obvious solution is to create a copy of the sender before we dispatch the Future, just like:

// this is OK
  1. class Caplin extends Actor {
  2.   def recieve = {
  3.     case _ =>
  4.       val mySender = sender
  5.       Future { mySender ! "カピバラ" }
  6.   }
  7. }

This works OK. But I promised to talk about scala.util.DynamicVariable in the blog post’s title, didn’t I? Let’s see how we could implement the same thing by using it then.

DynamicVariable is pretty much like Java’s ThreadLocal. It exposes a value, which may be set to different values per Thread – so that’s exactly what we need to safe-guard our code agains mixing up the sender values.

// dynamic variable version
  1. class Caplin extends Actor {
  2.   val Sender = new DynamicVariable[ActorRef](self)
  3.  
  4.   def recieve = {
  5.     case "カピバラ" => "Why am I talking with myself?"
  6.     case _         =>
  7.       Sender.withValue(sender) {
  8.         Future { Sender.value ! "カピバラ" }
  9.       }
  10.   } 
  11. }

As you can see, first we create the “thread-local” value Sender and before we dispatch the new Future we wrap the code with DynamicVariable::withValue which assures that within this block of code – the value of sender is guaranteed to be what we passed in there.

Where does the name DynamicVariable come from you might ask? It’s clearly not dynamic in the “Type” way – it’s strictly typed as you’d expect it to be. Well, turns out that what we see here is an implementation of Dynamic Scoping (read up about it on Wikipedia).

That’s it for now, check back later to see some more Scala in action, as I’m just in the middle of preparing my Scala + Android talk (version 2!). While this example maybe not the best case (it’s quite a bit of code compared to “just use a val”) on where to use DynamicVariable, I hope more of you are now aware of the close over sender issue, as well as this nice nifty class from Scala.

Tags: , , ,

Scala powered streaming migrations in MongoDB on millions of records

Posted by Ktoso under coding, guide, scala (No Respond)

In my project at work we have some production systems using MongoDB as their primary database. Quite a number of the collections we have there could be called “huge” and we sometimes have to migrate data from one (let’s call it a “schema” for simplicity – ok?) schema to another one, or perform some statistics on the entire collection.

So the first thing you’d try to do is a typical foreach on a rogue query like this:

… and do whatever stats etc you need to do for each of the elements. Turns out that there’s quite a few reasons this sucks (bad time), and wouldn’t even get close to computing the entire thing. Some problems are:

  • the cursor WILL timeout if used like this
  • we’re mapping stuff to objects of Person, so that takes time and memory

(ps: we could do worse than the example above – don’t try to get a huge collection in memory… ;-)). Moving on to the solution, there’s a few things we have to do here. First, stop the cursor from timing out, which can be achieved by setting the apropriate option on the Cursor:

As you’ve already noticed… we’re down to the low-level api here… For now let’s say I’m ok with that (we’ll enable rogue a bit later again). So putting this in context, you’d have to write:

Ok, here you can use the cursor and iterate over the whole collection. That’s quite a bit of code but we got to the point the cursor is usable, and won’t time out… The next step is to package this up in a nice function, and allow passing in a rogue query object. I’ll paste in the end result of those steps so you can analise it yourself:

There is a minor annoyance with writing query.asDBObject.some (which is Scalaz’s equivalent of Some(query.asDBObject))… Let’s fix this with a simple delegating function:

But I still am not happy with this. As already mentioned, we’re dealing with huge collections, so the processing may well take up to a day sometimes. Let’s see what we can cut off here… Oh yeah – let’s not select fields we don’t use. Let’s revise our code to implement a streamSelect version of the above, which will only select fields we’re interested in from mongo:

Here we only select the fields we really need – which has proven to be a big performance boost. It’s quite readable, though I wasn’t able to get rid of the

[Person]

type parameter in the

select

helper. We’re using such streams wherever we know there’s “a lot of stuff to process” or in so-called “preloads”, where we compute a set of values from an entire collection for alter re-use.

You may have noticed that all this has not been very TypeSafe (the callback isn’t). So… you might ask, did we implement a “typesafe version of our streams? And in fact we did, though it’s tuple based, so we had to implement the same thing multiple times – for different tuples. I’ll paste just the usage of the TypeSafe version here (and if you’re interested I can do a follow-up blog post about them):

What we’ve gained using those streams is the ability to easily write all the migrations we need to, and we’re still elastic enough to for example – remove fields from the collection (with some processing, so just a mongo query won’t be enough). In streamSelect we’re open to have multiple case statements, so even if the collection is not homogenic, we can match null on some of the fields and still proceed over the entire collection – if needed.

Anyway, I hope you found this bunch of code snippets interesting or useful – we certainly do in our day to day coding :-)

Tags: , , , , , , ,

Scala + Android @ Mobilization 2012 – w Łodzi

Posted by Ktoso under android, coding, polish, scala (No Respond)

Dopiero minęło kilka tygodni od łodzkiej Mobilizacji a już można oglądnąć nagrania z tej konferencji – wzorowa organizacja muszę powiedzieć :-) Sam content też oceniam dość wysoko – bądź co bądź, zrodziła się nam kolejna “największa w swojej kategorii”, to znaczy konferencji dot. mobile, impreza w Polsce :-) Nasze Krakowskie wydarzenia będą miały nie lada konkurencję jak widać.

Ja, na przekór swoim normalnym wyborom, przeszedłem się na kilka prezentacji związanych z iOS aby zobaczyć jak po tamtej stronie kabla się programuje. Generalnie jednak nie przekonałem się i zostanę z DVMem (z wielu przyczyn), ale może nie koniecznie już Javą na nim.

O tym właśnie była moja prezentacja (Scala my Android), która jak dziś mnie poinformowano została już umieszczona online. Zachęcam do oglądnięcia, albo przeglądnięcia slajdów na GitHubie:

(Warning english readers – the talk is in Polish, though the slides are in english, so feel free to take a look at them)

Wracając do organizacji / organizatorów… Miałem przyjemność spotkać się z Mariuszem tydzień wcześniej w Pradze podczas zjazdu GDG i opowiadał mi co i jak im idzie z dopinaniem wszystkiego na ostatni guzik, a wiedząc ile roboty (czasu) kosztują takie wydarzenia, na prawdę gratuluję i jestem pod wrażeniem roboty Marka i Mariusza jaką w to włożyli :-) Swoją drogą ciekaw jestem czy łódź w związku z otwarciem tam biura przez Samsunga stanie się “polskim miastem mobajla”… :-)

In other news… pojawiło się nowe logo na blogu wskazujące na to że czymś tam jestem. Tym razem mowa o DZone Most Valuable Blogger. Hura!

Tags: , , , , ,

Easily cross-compile and release scala projects with sbt

Posted by Ktoso under coding, english, guide (No Respond)

Scala’s lack of compatibility

Ok, lets get over with it – Scala is not binary compatible between minor versions (Where by minor I mean: MAJOR.MINOR.UPDATE). This raises the obvious problem that users of your library may be spread among 2.9.2 and 2.10.0 for example. And while your library would work fine with any of those versions, you’ll need to recompile and republish it two times – for those users.

Sounds like a pain, doesn’t it? Well, it is. The Scala ecosystem is currently fighting this problem with stabilizing scala itself, and libraries do released way quicker for new scala releases than before. Let’s see how we can bring my scala-rainbow library to new users with as little pain as possibe, shall we?

The goal is:

  • Compile the project using 2 (or more) scala versions,
  • Deploy all to the Sonatype OSS repository,
  • do all this using just one command.

Prepare sbt plugins

There are some plugins we’ll need to pimp sbt with in order to achieve our goal. The fist one is xsbt-gpg-plugin which gives us access to GPG from within SBT. Adding it to the project (or global settings) is as simple as adding those lines to project/plugins.sbt (mind the blank lines, they’re important – really):

// plugins.sbt
  1. resolvers += Resolver.url("sbt-plugin-releases",
  2.   new URL("http://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-releases/"))(Resolver.ivyStylePatterns)
  3.  
  4. addSbtPlugin("com.jsuereth" % "xsbt-gpg-plugin" % "0.6")

Next you’ll want to generate your pgp key, that we’ll use to sign your the library JAR’s (Sonatype requires us to do so). You can either follow the plugin’s way of doing this, as explained here or do it the GPG way which is really well described on this ubuntu manual page.

After you’ve created your key, and uploaded the public key, make sure that the “asc” (read up on the ubuntu manual about this) version of the key is located (or symlinked) in:

~/.sbt/gpg/my_funky_key.asc

As this is the place the sbt gpg plugin will look for keys to sign your JARs with.

Cross compilation

Next you should prepare sbt for cross compilation. I tend to prepare such settings in a separate value, which I use in all Project’s next. So you’d end up with a setting like this:

// Build.scala
  1. val buildSettings = Defaults.defaultSettings ++ Seq(
  2.   organization := "pl.project13.scala",
  3.   name := "rainbow",
  4.   version := "0.1",
  5.   scalaVersion := "2.10.0-M3",
  6.   crossScalaVersions := Seq("2.9.1", "2.9.2", "2.10.0-M3"),
  7.   libraryDependencies ++= dependencies
  8. )

Notice how right next to the typical “scalaVersion” setting, we’re using “crossScalaVersions”, where we define which other Scala versions this library should be compiled and released with. This is going to be used while the package, as well as publish commands.

The above buildSettings are used like this in your Project (in case you’ve forgotten):

// Build.scala
  1.  
  2. lazy val root = Project (
  3.   "rainbow",
  4.   file("."),
  5.   settings = buildSettings ++ sonatypeSettings ++
  6.     Seq(/*…*/)
  7. )

Where sonatypeSettings is a bit of XML boilerplate, containing things like your SCM url, license and so on. If you’re stuck with building up your Build.scala, take a look at Build.scala from scala-rainbow, as it’s “as simple as it gets” :-)

In terms of Sonatype configuration just take a look at this wiki page what you’ll need to set up – or just refer to the above linked Build.scala. I won’t get more into detail about that, as it has been covered very well in the internet already, not as much as cross building… :-)

Let’s cross compile + publish!

They key element of this paragraph has already been spoiled a bit by it’s title. The command we’ll use to perform all 3steps needed to deploy our library, for 3 Scala versions to sonatype is…

+ publish

The plus before the command means “for all scala versions”, you can read more about Cross Building on the SBT wiki page about it.

And as a small apetizer, here’s how the output will look (trimmed down ;-)):

# example output
  1.  
  2. > + publish
  3.   Setting version to 2.9.1
  4.   …
  5.   [success] Total time: 0 s, completed Sep 27, 2012 12:16:52 AM   
  6.   Setting version to 2.9.2
  7.   …
  8.   [success] Total time: 2 s, completed Sep 27, 2012 12:16:54 AM
  9.   Setting version to 2.10.0-M3
  10.   …
  11.   [success] Total time: 0 s, completed Sep 27, 2012 12:16:54 AM
  12.   Setting version to 2.10.0-M3
  13.   >

So as you can see – just one command, but it triggered for all Scala versions, and SBT took care of all scala version switching and executing of those tasks.

Having that said… It’s really easy nowadays to cross compile your projects to support multiple Scala versions. If you’re coding a library – be sure to include these configurations in your Build!


This posi is now officialy a DZone Big Link! :-)

Tags: , , , ,

Around the world, around the world…

Posted by Ktoso under android, fun (No Respond)

As in the upcoming weeks I’ll be again talking and meeting people around Europe, at some pretty cool places / conferences I thought I’d link back to them and share a few words on what I’m currently mostly presenting about etc :-)

First up, this week:

  • we’re having an Google Developer Group Leaders Summit in Prague – although no concrete official name for it has sufraced AFAIK. It’s a meetup of different GDG representatives to try to built a stronger colaborative network between cities and countries – can’t wait to share some thoughts and get some feedback on growing our user groups.

Then there’s the:

  • Mobilization conference on the 22th in Lódź where I’ll be giving a talk about joining Scala with Android – and the benefits of such a curagous mixture. The conference is free – so feel free to drop by if you’re interested! By the way, the local GDG and JUG are working on this one, so it’s another nice example on colaboration of multiple UGs…

Then there’s a small pause, until the 29th of November

  • When the second Java Riga Day will take place (Riga is the capitol of Latvia). We’ve, together with Andrzej Grzesik, had the chance to meet the organiser of this conference on this year’s JUG Leaders Meetup – so we’re pretty confident the conf will be a success :-) Andrzej will be speaking there too (topic TBD), and I’ll give a short Scala tutorial – with lot’s of hands-on. We’re also planing to help JRD as GeeCON – let’s see what we can bring in there for the participants… :-]

And in the far future I’ll be doing a week-long Scala workshop to hone developers into hardcore Type Masters… But that’s quite some time until then… :-)

PS: If you’re in Cracow on the 15th of September – Hackerspace KRK is organizing an Arduino Workshop - definitely worth checking out! I’d love to be there myself but sadly won’t be able to. GDG is helping there out by providing a few Arduino devices – a small help, but we hope you’ll enjoy the workshop! All kudos for the event goes to the Hackerspace founders though :-]

Tags: , ,

Implementing the “Chrum” daily stand up @ SoftwareMill

Posted by Ktoso under english, fun (3 Responds)

At SoftwareMill – we’re fully distributed. That means that you end up working with people from all around Poland (or Australia, Africa, or the United States), and there’s no place you could call the “company office”. It has it’s upsides as well as downsides – as most things. I personally really love the freedom such way of working gives you… and the project is fun too! ;-)

Anyway, one of the issues a team has to face when working in such environment is: “How to feel united with the other people and teams in the Company?” A hard question indeed. Just chatting won’t do, if you’ve ever worked as “the remote person” you know that. The typical scrum standup doesn’t make sense, especially if:

  • the “team” on such standup is the entire company (that’s around 18 people),
  • there’s a bunch of projects in the company, usually with small teams of up to 4 people on board,
  • the goal… isn’t to dumbly/boringly answer the boring 3 scrum questions.

chrum-sml-2013

The Daily Chrum *

The “Chrum” (the sound pigs do) is a process invented and perfected during the two years of softwaremills’ existence – and we’re still changing it to adapt to our needs. So, what are those needs? First, we don’t really care about “what did you do in detail yesterday”, that’s why we communicate all the time on chats, jira etc – no need to hear it again, and you’ll bore people from other projects to death ;-) What we really use the Chrum for is actually… socialising, it’s one of those rare moments we’re all online together – with audio and video. So I’ll actually recognise my partner on a conference because we see each other daily – remote teams problem 1) solved :-)
There’s a number of tools that help us with this:
  • Chats – we use Skype , although most of us would like some other tool (XMPP based), still – most clients know and like Skype, so instead of having one more tool to chat with, we stich with this one. It’s also the place where most of the communication takes place, you can share links etc here – even during the daily call,
  • PushToTalk – we use TeamSpeak, yeah the one people use for Counter Strike ;-) It works way better than Skype for 18 people, and some teams also use it during their day – to get the feeling of “working in the same room”, you just push and then talk. We use this as Audio tool during the Chrum, as it eliminates any background noises from the 17 other participants,
  • Video Conferencing – we use Big Blue Button for this. For a number of reasons, one of them is: it’s free and open source. Another is – best video quality out there for such big meetings (remember – we’re up to 18 people). We’re hosting it ourselves on EC2, and I’ve created a small cron util that starts the BBB server right before the meeting, and shuts it down again after it. The reason behind this is that we need the most powerful instance there is on EC2 to handle this call nicely, and that costs quite a bit – and we don’t need this instance to be up for all the day obviously ;-) PS: For smaller meetings, we found Google Hangouts to be the most pleasant to work with.

A brief introduction to Chrum

The flow of the meeting may seem a bit weird, but remember – it’s something that evolved out of two years of experimenting with it, and we’re quite happy with the current formula, but we’re always trying something new to improve it nevertheless.

The Chrum has two iterations and then we open up a free discussion, which is marked by saying “bakłażan” (pl. eggplant):

0. The Chrum Master assembles everyone and reminds the "4th question"

1. Project round
1.1. Feelings in the project?
1.2. Personal round questions

2. Personal round
2.1. "4th question"
2.2. [optional] What's blocking you?
2.3. [optional] Got something cool to showoff today? (work / non-work)

3. Bakłażan

So… this may seem a bit weird and confusing, so let’s explain it a bit in detail.

The first step is to get everyone on BBB and audio – sometimes people are “in the zone” or AFK, so you have to do some “ping ping” on the global chat – this, and thinking of a 4th question (we’ll get to it) are the responsibilities of the Chrum Master (and keeping the chit-chat short – until the Bakłażan phase).

First, in the projects round – one person from a team reports the general “feel” of that team on that day. Maybe there’s a release coming up, or there was a great success etc. We think that by formulating this question like this, we get to know what’s up in the other projects, and avoid getting into technical details, which people from other projects wouldn’t understand (too much domain knowledge involved). Then that person continues with answering the personal questions.

Once the “projects” round finishes, team members who didn’t speak yet are asked to answer the “4th question”. Why is it called the 4th when in reality it’s the 2nd now? Well, for legacy reasons – while we did a classical scrum standup, it was the 4th indeed, because: 1) what I did yesterday? 2) what I’ll do today 3) what’s blocking me? and then the 4th, which we’ve added ourselves. The idea of the 4th question, is to think of some, fun question that allows us to get to know each other, even though we’re not collocated. So it may be a music or literature question etc. By the time we’ve ran out of “typical” questions for this, and it gets more fun to think of a cool 4th question to ask. The chrum master (which is chosen once a week – well, usually just someone want’s to do it anyway :-)) gets the privilege to ask this question.

We recently added the “showoff” question, as sometimes we have such things – like we’ve found a cool library, or something else but forget to tell everyone about it – maybe it’s team specific but may interest other people too. We’ve been trying it out since monday and so far I feel it will be a nice addition.

It’s worth mentioning that the last questions are optional. Up until recently it wasn’t and typically there was a full round of people reporting “no blockers on my end”. So we’ve made it optional now – if you’re blocked, yell out – if not, well there’s not much to talk about then, right?

After all participants have answered the questions, the chrum master says “Bakłażan”, and we’re free to either leave the call right now, or hang around for however long you want and chat a bit. Possibly following up the blockers mentioned, or the cool project someone just showed etc.

So… this is how we chrum. It may seem a bit complicated, but I’ve found that it’s shockingly well organised, and everyone knows when and what to say. We get the benefit of knowing, on a level we care, about other projects and we have both a bit of induced getting to know each other (the 4th question) as well as the free for all chat after the chrum call – the bakłażan phase.

* Chrum – well, that’s my name for it. Let’s see it it gets accepted ;-)

If you want to know a bit more about us, ping me via email or chat or if you’re the passive type – there’s a nice interview with Paweł Wrzeszcz on web.gov.pl – definitely worth checking out IMO :-)

Tags: , , , , , , ,

[Google I/O Extended Kraków] + [Google Guava]

Posted by Ktoso under coding, gdg (No Respond)

Last week we’ve organized a Google I/O Extended in Kraków. As lead of the GDG (Google Developer Group) around here, and the only Kraków member that was in Poland on this day, it was a bit hasty but we somehow managed to pull off a 2 day long event filled with live video streaming from Google IO and some (3) presentations on site from local Devs about Google related technology.

Sadly I didn’t take more pictures on the first day, where we had three times the number of participants as seen on the pic above (from day 2). Oh well ;-) Here’s some more pictures for those interested.

We had 3 on site talks, one about Go (by Mateusz Czapliński), a very neat programming low-levelish (in the meaning of “like c”) language, my Google Guava presentation (Guava – slides available here), and on the second day a quick intro to Google Closure Tools / Library by Sebastian Poręba. In the meantime we chatted a bit and watched the live streams, like the keynotes on both days, for example.

Anyway, here is the the Go talk:

And here’s my Guava talk. By the way, it’s highly recommended you check it out if you write Java and don’t use Guava yet (yeah, I’ve heard there are such people still… ;-))

My slides are available under this url: https://github.com/gdg-krakow/google-io-ext-2012-guava as repo on github or you can view the presentation slides online here.

Tags: , , , ,