turducken - divide and conquer large gwt apps with multiple teams

Post on 23-Jun-2015

2.183 Views

Category:

Technology

1 Downloads

Preview:

Click to see full reader

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

Turducken

Rob KeaneGoogle / Ad Exchange Front Endrkeane@google.com

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

A note on the name...

Turkey + Duck + Chicken

For this...

...not this

Large projects

teams?release cycles?testers?frameworks?

Multiple...

Terminology

In the context of this talk...

Module == GWT Module with entry point

One last note...

This is a design pattern not a library

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

Turducken

Bob’s GWT App

Bob has a sticker site

bobs-sticker-emporium.com

BOB’S STICKERSStickers

BUY! BUY! BUY!

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!

Things are getting complex

➔ Still one giant GWT module

➔ Compilation takes several minutes

➔ A few megabytes of JS

➔ 5 teams!

➔ Continuous integration

➔ Release coordination

What should Bob do?

How do you split up a large GWT project?

One GWT module× One release

× One build

× Very large if code isn’t split properly

× Difficult to test

Many GWT modules× Full page reloads

× Code can’t be split between modules

One GWT module?

Many GWT modules?ಠ_ಠ

ಠ_ಠ

Ultimately multiple GWT modules

is the only real option

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!

Full page refresh between each module

Bob

half of aggregate user latency

Research showed that

was due to full page reloads

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

Turducken

Tab A(GWT)

Tab B(GWT)

Tab C(GWT)

Container (GWT Module)

Inter-app Event Bus (JSNI)

Virtual historian

Virtual historian

Virtual historian

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

Yes.This actually works

Loading all of the modules?

Bob’s container

bobs-sticker-emporium.com

BOB’S STICKERSStickers

BUY!

Create your own!

Your Cart (2)

Sell a sticker!

Load multiple GWT modules?

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

➔ Everything lives in the same container

Memory usage

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

loading new modules

// 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

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;

}

When Module “TAB_1” is loaded →

When Module “TAB_2” is loaded →

But I really want @external CSS...

/* 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

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

All problems in computer science can be solved by

another level of indirection

Butler Lampson

Tab A(GWT)

Tab B(GWT)

Tab C(GWT)

Container (GWT Module)

Inter-app Event Bus (JSNI)

Virtual historian

Virtual historian

Virtual historian

Virtual History Implementation

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

Container History

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

For example:#MODULE_A/MyPlace

instead of#MyPlace

Tab A(GWT)

Tab B(GWT)

Tab C(GWT)

Container (GWT Module)

Inter-app Event Bus (JSNI)

Virtual historian

Virtual historian

Virtual historian

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

Code example

// Container

InterAppEventBus.subscribe(“HISTORY_CHANGE”, updateUrlHandler);

// Virtual History in a submodule

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

Message trace for historyEvent bus

Change to virtual history

Module load event

Real URL is changed

Virtual Historian Container Browser

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

The future

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

But wait!

There’s more.

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

Turducken

An inter-app event bus opens up some interesting doors

It’s all about the event bus

Inter-app communication

Load another module via an event

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

➔ Chat module

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

Invisible Modules

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

➔ Monitoring session➔ Caching data for multiple modules

Non-GWT “modules”

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

Where’s the code?

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

...but we are considering it

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

wow

wow

many modules

different releasessuch performance

no reloads

Questions?

top related