turducken - divide and conquer large gwt apps with multiple teams

52
Turducken Rob Keane Google / Ad Exchange Front End [email protected] Divide and conquer large GWT apps with multiple teams

Upload: robert-keane

Post on 23-Jun-2015

2.184 views

Category:

Technology


1 download

DESCRIPTION

Complex GWT apps can involve multiple teams with different release cycles. Compile times can quickly become prohibitive when your codebase grows into millions of lines. “Turducken” is a technique to combine multiple GWT apps that can be built and released by separate teams while providing a seamless, snappy user experience.

TRANSCRIPT

Page 1: Turducken - Divide and Conquer large GWT apps with multiple teams

Turducken

Rob KeaneGoogle / Ad Exchange Front [email protected]

Divide and conquer large GWT apps with multiple teams

Page 2: Turducken - Divide and Conquer large GWT apps with multiple teams

Complex GWT apps can involve multiple teams with different release cycles. Compile times can quickly become prohibitive when your codebase grows into millions of lines.

“Turducken” is a design pattern to combine multiple GWT apps that can be built and released by separate teams while providing a seamless, snappy user experience

Turducken

Page 3: Turducken - Divide and Conquer large GWT apps with multiple teams

A note on the name...

Turkey + Duck + Chicken

Page 4: Turducken - Divide and Conquer large GWT apps with multiple teams

For this...

...not this

Page 5: Turducken - Divide and Conquer large GWT apps with multiple teams

Large projects

teams?release cycles?testers?frameworks?

Multiple...

Page 6: Turducken - Divide and Conquer large GWT apps with multiple teams

Terminology

In the context of this talk...

Module == GWT Module with entry point

Page 7: Turducken - Divide and Conquer large GWT apps with multiple teams

One last note...

This is a design pattern not a library

Page 8: Turducken - Divide and Conquer large GWT apps with multiple teams

1. Bob’s Sticker Emporium2. Conquering Multiple Entry Points3. Other uses

Turducken

Page 9: Turducken - Divide and Conquer large GWT apps with multiple teams

Bob’s GWT App

Bob has a sticker site

bobs-sticker-emporium.com

BOB’S STICKERSStickers

BUY! BUY! BUY!

Page 10: Turducken - Divide and Conquer large GWT apps with multiple teams

Success!

Bob adds more options...

bobs-sticker-emporium.com

BOB’S STICKERSStickers

BUY! BUY! BUY!

Create your own!

Customize Customize Customize

Your Cart (2)

Sell a sticker!

Page 11: Turducken - Divide and Conquer large GWT apps with multiple teams

Things are getting complex

➔ Still one giant GWT module

➔ Compilation takes several minutes

➔ A few megabytes of JS

➔ 5 teams!

➔ Continuous integration

➔ Release coordination

Page 12: Turducken - Divide and Conquer large GWT apps with multiple teams

What should Bob do?

How do you split up a large GWT project?

Page 13: Turducken - Divide and Conquer large GWT apps with multiple teams

One GWT module× One release

× One build

× Very large if code isn’t split properly

× Difficult to test

Page 14: Turducken - Divide and Conquer large GWT apps with multiple teams

Many GWT modules× Full page reloads

× Code can’t be split between modules

Page 15: Turducken - Divide and Conquer large GWT apps with multiple teams

One GWT module?

Many GWT modules?ಠ_ಠ

ಠ_ಠ

Page 16: Turducken - Divide and Conquer large GWT apps with multiple teams

Ultimately multiple GWT modules

is the only real option

Page 17: Turducken - Divide and Conquer large GWT apps with multiple teams

Multiple modules

Split into multiple GWT entry points

bobs-sticker-emporium.com

BOB’S STICKERSStickers

BUY! BUY! BUY!

Create your own!

Customize Customize Customize

Your Cart (2)

Sell a sticker!

Page 18: Turducken - Divide and Conquer large GWT apps with multiple teams

Full page refresh between each module

Bob

Page 19: Turducken - Divide and Conquer large GWT apps with multiple teams

half of aggregate user latency

Research showed that

was due to full page reloads

Page 20: Turducken - Divide and Conquer large GWT apps with multiple teams

1. Bob’s Sticker Emporium2. Conquering Multiple Entry Points3. Other uses

Turducken

Page 21: Turducken - Divide and Conquer large GWT apps with multiple teams

Tab A(GWT)

Tab B(GWT)

Tab C(GWT)

Container (GWT Module)

Inter-app Event Bus (JSNI)

Virtual historian

Virtual historian

Virtual historian

Page 22: Turducken - Divide and Conquer large GWT apps with multiple teams

The container

➔ A GWT module (mostly)➔ The first thing to load on the page➔ Loads the other modules on demand➔ Communicates with modules through

inter-app event bus

Page 23: Turducken - Divide and Conquer large GWT apps with multiple teams

Yes.This actually works

Loading all of the modules?

Page 24: Turducken - Divide and Conquer large GWT apps with multiple teams

Bob’s container

bobs-sticker-emporium.com

BOB’S STICKERSStickers

BUY!

Create your own!

Your Cart (2)

Sell a sticker!

Page 25: Turducken - Divide and Conquer large GWT apps with multiple teams

Load multiple GWT modules?

➔ When a module is loaded, a <script> tag is added to the <head>

➔ Everything lives in the same container

Page 26: Turducken - Divide and Conquer large GWT apps with multiple teams

Memory usage

➔ Browsers are good at hiding elements➔ Memory only increases marginally when

loading new modules

Page 27: Turducken - Divide and Conquer large GWT apps with multiple teams
Page 28: Turducken - Divide and Conquer large GWT apps with multiple teams

// OldRootPanel.get().add(myRootWidget);

// NewContainerHelper.getModulePanel().add(myRootWidget);

<body> <div id=”modules”> <div id=”TAB_1_ROOT”>...</div> <div id=”TAB_2_ROOT” style=”display:none”>...</div> <div id=”TAB_3_ROOT” style=”display:none”>...</div> </div></body>

DOM Assumptions

Page 29: Turducken - Divide and Conquer large GWT apps with multiple teams

CSS➔ Avoid @external as much as possible

➔ Avoid styling tags

... unless the style is truly global

➔ Should be in a “global” CSS file> global.css

a {

color: #999;

}

Page 30: Turducken - Divide and Conquer large GWT apps with multiple teams

When Module “TAB_1” is loaded →

When Module “TAB_2” is loaded →

But I really want @external CSS...

Page 31: Turducken - Divide and Conquer large GWT apps with multiple teams

/* no, no, no */@external .title;.title { color: pink; font-size: 72px;}

/* that’s better */@external .title;#TAB_1 .title { color: pink; font-size: 72px;}

CSS example

Page 32: Turducken - Divide and Conquer large GWT apps with multiple teams

There’s just one tiny, little issue...

Page 33: Turducken - Divide and Conquer large GWT apps with multiple teams

All problems in computer science can be solved by

another level of indirection

Butler Lampson

Page 34: Turducken - Divide and Conquer large GWT apps with multiple teams

Tab A(GWT)

Tab B(GWT)

Tab C(GWT)

Container (GWT Module)

Inter-app Event Bus (JSNI)

Virtual historian

Virtual historian

Virtual historian

Page 35: Turducken - Divide and Conquer large GWT apps with multiple teams

Virtual History Implementation

An history implementation that doesn’t alter the “real” URL but instead sends an event

Page 36: Turducken - Divide and Conquer large GWT apps with multiple teams

Container History

Produces a “safe” URL that contains information about the module

For example:#MODULE_A/MyPlace

instead of#MyPlace

Page 37: Turducken - Divide and Conquer large GWT apps with multiple teams

Tab A(GWT)

Tab B(GWT)

Tab C(GWT)

Container (GWT Module)

Inter-app Event Bus (JSNI)

Virtual historian

Virtual historian

Virtual historian

Page 38: Turducken - Divide and Conquer large GWT apps with multiple teams

The event bus that broadcasts between modules needs to be JSNI since it must communicate between GWT modules

A simple publish/subscribe interface will do

Event bus implementation

Page 39: Turducken - Divide and Conquer large GWT apps with multiple teams

Code example

// Container

InterAppEventBus.subscribe(“HISTORY_CHANGE”, updateUrlHandler);

// Virtual History in a submodule

InterAppEventBus.publish(“HISTORY_CHANGE”, “myNewUrl”);

Page 40: Turducken - Divide and Conquer large GWT apps with multiple teams

Message trace for historyEvent bus

Change to virtual history

Module load event

Real URL is changed

Virtual Historian Container Browser

Page 41: Turducken - Divide and Conquer large GWT apps with multiple teams

Summary of Turducken

➔ Separate your app into multiple entry points➔ A container module manages loading the

submodules➔ Carefully manage your CSS➔ The submodules talk to a virtual historian➔ A JavaScript/JSNI InterAppEventBus handles

events between modules and the container➔ Events are broadcast that the container handles

to alter the real URL

Page 42: Turducken - Divide and Conquer large GWT apps with multiple teams

The future

➔ Shadow DOM eliminates a lot of the issues➔ Eliminate JSNI with GWT 3.0

Page 43: Turducken - Divide and Conquer large GWT apps with multiple teams

But wait!

There’s more.

Page 44: Turducken - Divide and Conquer large GWT apps with multiple teams

1. Bob’s Sticker Emporium2. Conquering Multiple Entry Points3. Other uses

Turducken

Page 45: Turducken - Divide and Conquer large GWT apps with multiple teams

An inter-app event bus opens up some interesting doors

It’s all about the event bus

Page 46: Turducken - Divide and Conquer large GWT apps with multiple teams

Inter-app communication

Load another module via an event

➔ Settings Module◆ Change settings from other modules◆ Global “Accept ToS” message

➔ Chat module

Page 47: Turducken - Divide and Conquer large GWT apps with multiple teams

Example

➔ One team maintains “Chat” functionality➔ Another team maintains a “Profile” page➔ Launch a chat with a person from their

profile➔ Chat module doesn’t always need to be

loaded➔ Limited coupling between modules

Page 48: Turducken - Divide and Conquer large GWT apps with multiple teams

Invisible Modules

There can be “background” modules that aren’t visible but handle events

➔ Monitoring session➔ Caching data for multiple modules

Page 49: Turducken - Divide and Conquer large GWT apps with multiple teams

Non-GWT “modules”

➔ Follow the same CSS approach➔ Write an virtual history implementation➔ Add hashPrefix to $location in Angular

Page 50: Turducken - Divide and Conquer large GWT apps with multiple teams

Where’s the code?

➔ A few small parts➔ A design pattern, not a library➔ Tends to be application specific

...but we are considering it

Page 51: Turducken - Divide and Conquer large GWT apps with multiple teams

Complex GWT apps can involve multiple teams with different release cycles. Compile times can quickly become prohibitive when your codebase grows into millions of lines.

“Turducken” is a design pattern to combine multiple GWT apps that can be built and released by separate teams while providing a seamless, snappy user experience

Turducken

Page 52: Turducken - Divide and Conquer large GWT apps with multiple teams

wow

wow

many modules

different releasessuch performance

no reloads

Questions?