continuous innovation @ gilt groupe
DESCRIPTION
This is a talk about different ways we enable continuous innovation. Working bottom-up from tech stack through how we organize teams, to how we do architecture & organize teams of teams, we share various approaches we've found work well.TRANSCRIPT
Continuous Innovation
Eric Bowman VP Architecture
Gilt Groupe
@[email protected] http://tech.gilt.com
http://www.flickr.com/photos/nationaalarchief/4193508328/sizes/o/in/photolist-7oyPVJ-7oyPWW-7oyPYf-7oyQ1s-7oyQ4u-7oyQh7-7oyQju-7oyQmm-7oyQqS-7oDszB-a7vaUw-fJHB9E-fJHBbj-fJHBaw-fJHB8N-fJrhsz-9uzYLJ-f5hWTe-f5i3Fv-f5ibHt-f5i6T2-f5ibEH-f5ibFz-f5ibGF-f5i3G8-fa97G7-f5i6Sk-f5ibDa-f5i3EH-f5i3E2-f5ifwt-f5i6Tk-f5i6PX-f5i3CV-fadccE-fadcgw-fadcf5-7JxdSE-8F3Akp-8F3AjM-8F6Lah-7GBRia-8PWU2Q-8PWU8j-dbzybh-9Nk8fN-8wBt83-cweZi9-8PWYgo-8PWYTN-8PTRqn/
http://megmurph.com/wp-content/uploads/2013/03/success-1.jpg
http://upload.wikimedia.org/wikipedia/commons/7/7f/Structure_Paris_les_Halles.jpg
http://upload.wikimedia.org/wikipedia/commons/thumb/1/19/Train_wreck_at_Montparnasse_1895.jpg/853px-Train_wreck_at_Montparnasse_1895.jpg
http://www.andpop.com/wp-content/uploads/2013/01/Screen-Shot-2013-01-03-at-11.18.47-AM.png
http://ontherealny.com/wp-content/uploads/2013/01/OfficeSpace.jpg
http://500motivators.com/motivate/me/motivation-its-not-that-im-lazy-i-just-dont-care/
A Social Experiment.
http://i.imgur.com/rjhDNfQ.jpg
http://1.bp.blogspot.com/_gS-Swh3xoXc/TGBKtRIB2PI/AAAAAAAAA8o/j-2oz2Nhdm8/s1600/Dave+driving+Antique+Car.JPG
http://bothsides.wpengine.netdna-cdn.com/wp-content/uploads/2013/09/Transparency.jpg
http://i.imgur.com/8yj8CqJ.jpg
http://i.imgur.com/6vCz2.jpg
http://www.flickr.com/photos/dno1967b/8600410187/sizes/h/in/photolist-e6Zmjg-a9Ton2-9GUHja-ehXg1P-aaryES-fbpos6-fKqHKk-exbKfX-aarwxu-aawuWM-aaoH6B-8T5YTg-858k1A-ajFRPZ-7N7783/
object Build extends ClientServerCoreProject with ClientServerCoreDeps { val name = "svc-persistent-session" val servicePort = 8260 override val ioncannonTrack = IonCannon.FastTrack override def coreDeps = Seq( "com.giltgroupe" %% "commons-util" % "5.2.3" ) ++ defaultTestLibs override def clientDeps = Seq( "com.giltgroupe" %% "commons-core" % "5.2.3", "com.giltgroupe" %% "commons-test" % "5.2.3" % "test" ) ++ defaultTestLibs override def serverDeps = Seq( "com.giltgroupe" %% "commons-core" % "5.2.3", "com.giltgroupe" %% "commons-voldemort" % "1.1.1" % "compile->compile;endorsed->endorsed", "com.giltgroupe" %% "commons-squeryl" % "0.5.2", "com.gilt.service" %% "zookeeper" % "0.6.7" ) ++ gilt.ServiceFramework.dependencies("2.3.1") ++ defaultTestLibs }
$ sbt gilt-upgrade
object Build extends ClientServerCoreProject with ClientServerCoreDeps { val name = "svc-persistent-session" val servicePort = 8260 override val ioncannonTrack = IonCannon.FastTrack override def coreDeps = Seq( "com.giltgroupe" %% "commons-util" % "5.2.4" ) ++ defaultTestLibs override def clientDeps = Seq( "com.giltgroupe" %% "commons-core" % "5.2.4", "com.giltgroupe" %% "commons-test" % "5.2.4" % "test" ) ++ defaultTestLibs override def serverDeps = Seq( "com.giltgroupe" %% "commons-core" % "5.2.4", "com.giltgroupe" %% "commons-voldemort" % "1.1.1" % "compile->compile;endorsed->endorsed", "com.giltgroupe" %% "commons-squeryl" % "0.5.3", "com.gilt.service" %% "zookeeper" % "0.6.7" ) ++ gilt.ServiceFramework.dependencies("2.4.0") ++ defaultTestLibs }
@Path("/persistent-session") class PersistentSessionResource(storage: StorageApi) { ! @GET @Path("/{namespace}/{id}/{key}") def get(@PathParam("namespace") namespace: String, @PathParam("id") id: String, @PathParam("key") key: String): Option[core.Value] = { storage.get(makeKey(namespace, id, key)) }
trait Session { def get(key: String): Future[Option[Value]] } !private class SessionImpl(namespace: String, id: String) extends Session with CommonsClient[ServiceException] with CommonsClientConfig {
def get(key: String): Future[Option[Value]] = { getResponse(svcUri,
"persistent-session/%s/%s/%s".format(namespace, id, key)) { bytes => CommonsJson.parse[Option[core.Value]](bytes).map(
ValueImpl.apply) } }
abstract class SessionClientTest extends TestClients with Predictable { @Test def putValueCanBeGotBack() { val session = sessionClient.getSession(rndString()) val key = rndString() val value = rndString() session.get(key).get() should equal(None) session.put(key, Value(value)).get() session.get(key).get().get.value should equal(value) } } !@Functional class FunctionalSessionClientTest extends SessionClientTest with FunctionalTest @Capture class CaptureSessionClientTest extends SessionClientTest with CaptureTest @Mock class MockSessionClientTest extends SessionClientTest with MockTest
$ sbt release
val cluster = allocateCluster("svc-foo", "1.2.2") for (server <- cluster.allocateServers()) { deploySoftware(server, "svc-foo", "1.2.2") addToPool(server) } for (server <- findServers("svc-foo", "1.2.1")) { removeFromPool(server) } garbageCollect("svc-foo", "1.2.1")
http://i.imgur.com/OIpCx.jpg
http://www.recruitmenttakeout.com/wp-content/uploads/2013/04/brian.png
Openness. Autonomy.
Transparency. Trust.
Strategy
Strategy
Initiative 1Initiative
Initiative
Initiative
Initiative 1KPI
Initiative
Initiative 1KPI
Team
Tools for Emergent Centralization
Publish on the blog?
Have a party?
Release to production?
Anybody. Anytime.
Zero Waiting.
http://3.bp.blogspot.com/_q3ojg-NVpyU/TLMLUNGhgjI/AAAAAAAABS8/IJQSBSqII5s/s1600/compass.jpg
gilt.com
giltcity.com
gilttaste.com
parkandbond.com
Gilt Hom
e
gilt.com
giltcity.comgilttaste.comparkandbond.comGilt Homegilt.com
gilt.com
platform
http://shirt.woot.com/derby/entry/18736/positive-feedback-loop
Voluntary Adoption
• Move Fast • Fail Fast • Focus on Function • Enabled by Platform • Pick & Choose • Drives Platform Innovation • Teams Measured by KPIs
Shared UI
Features
Core
DB
ProductPlatform
• Move Slower • Proven Technologies • Focus on Scaling • Drives Product • Teams Measured by
Adoption
Shared UI
Features
Core
DB
ProductPlatform
Shared UI
Features
Core
DB
ProductPlatform Stronger than
the sum of its parts
http://4.bp.blogspot.com/-oemCGhrR6yw/UHnXg5LiiTI/AAAAAAAAHOI/JyZctjen3_4/s1600/simple+vs+complex.png
http://i.imgur.com/tUyGc.jpg
https://www.facebook.com/photo.php?fbid=403764539746425&set=a.289682334487980.65204.289626304493583&type=1&theater
http://pocketpause.com/woofwoof/wp-content/uploads/2012/12/IMG_6225.jpg
http://i.ytimg.com/vi/g8yN5fivBt8/0.jpg
http://marcelnunis.com/blog/wp-content/uploads/2011/12/coins.jpg
http://brettlegree.files.wordpress.com/sunset-joy-2-1.jpg
http://thumbs.dreamstime.com/z/boy-sleeping-hammock-5090586.jpg
http://online.portenf.sa.gov.au/sites/default/files/16_0.jpg
https://www.apertus.org/sites/default/files/bart_os.gif
http://creditmanagementassociation.org/wp-content/uploads/2013/03/mousetrap.jpg
http://i.imgur.com/Owoeyzi.jpg