6. Eric Ries:
“a startup is a human
institution designed to
deliver a new product or
service under conditions
of extreme uncertainty”
7. Traditional Product Development
(Progress: Advance To Next Stage)
Solution: Known
Requirements
Design
Implementation
Verification
Manteinance
Problem: Known
Eric Ries @ http://startuplessonslearned.blogspot.com/
8. Agile Development
(Progress: Running Tested Features)
Solution: Unknown
quot;Product Ownerquot; or
in-house customer
Problem: Known
Eric Ries @ http://startuplessonslearned.blogspot.com/
9. we should be able to
Embrace Change
Cost of Change
Traditional Development
Agile Development
Time
10. we should be able to
Embrace Change
• Refactoring
• Simple Design
• Test-Driven Development
• Continuous Integration
• Collective Code Ownership
• Incremental Design
• Emergent Design
• Pair Programming
• Project Automation
• Definition of Done
• Exploratory Testing
15. Use of Requested Features
7%
13%
45%
16%
19%
The biggest source of waste is
implementation of features nobody wants
Standish Group, CHAOS Report 2006
17. Steve Blank:
“software
development is a
discovery and a
learning process”
18. Lean Startup Development
(Progress:Validated Learning about Customers)
Customer Development
Solution: Unknown
Problem: Unknown
Eric Ries @ http://startuplessonslearned.blogspot.com/
19. Agile in a Waterfall world
Agile Test Maintenance
Concept
Development Alpha/Beta and Marketing
Debug, Fix
and Patch
20. Agile in a Waterfall world
Agile Test Maintenance
Concept
Development Alpha/Beta and Marketing
Debug, Fix
and Patch
21. Agile in a Waterfall world
Agile Test Maintenance
Concept
Development Alpha/Beta and Marketing
Debug, Fix
and Patch
22. Lean Startup Development
(Progress:Validated Learning about Customers)
IDEAS
• Reduce the
LEARN BUILD
cycle time
Minimum
• Eliminate waste
Marketable
Feature
• Optimize the
DATA CODE
whole
• Amplify learning
MEASURE
Eric Ries @ http://startuplessonslearned.blogspot.com/
31. Resource Oriented Architectures
GET /position/wqd3,wkd2,bke8 HTTP/1.1
Accept: text/plain
HTTP/1.1 200 OK
Content-Type: text/plain;format=fen
n
5k2/8/8/8/8/3Q4/8/3K4
32. Resource Oriented Architectures
GET /position/wqd3,wkd2,bke8 HTTP/1.1
Accept: image/png;q=0.8, text/plain;q=0.2
HTTP/1.1 200 OK
Content-Type: image/png
n
PNG...
33. Resource Oriented Architectures
GET /board/4815162342 HTTP/1.1
HTTP/1.1 200 OK
n
...
/position/wqd3,wkd1,bke7
/position/wqd3,wkd1,bke8
34. Resource Oriented Architectures
POST /board/4815162342 HTTP/1.1
n
move = d3-e8
HTTP/1.1 201 Created
n
...
/position/wqd3,wkd1,bke8
/position/wqe8,wkd1,bke8
35. Resource Oriented Architectures
GET /game/42 HTTP/1.1
HTTP/1.1 200 OK
n
board = /board/4815162342
white = /player/50298
black = /player/48192
37. Resource Oriented Architectures
Tim Berners-Lee
on Linked Data
“... almost 20 years ago I wanted to reframe the
way we use informations ... I invented the Word
Wide Web ... now is time for a new reframing...”
Tim Berners-Lee @ http://linkeddata.org
40. now we have a
Good Domain
but an
Ugly Interface
41. Ajax to rescue
// Interface can have its state
// but actually consumes many serverside
// resources in background
var game = {
quot;gamequot;: quot;/game/42quot;,
quot;boardquot;: quot;/board/4815162342quot;,
quot;positionquot;: quot;/position/” +
“rnbqkbnr-pppp1ppp-8-4p3-4P3-8-PPPP1PPP-RNBQKBNRquot;
}
var req = YAHOO.util.Connect.asyncRequest;
req('GET', position + '/piece/g1/moves', callback);
// 200 OK; moves = g1-e2, g1-f3, g1-h3
board.highlightSquares(quot;g1quot;, quot;e2quot;, quot;f3quot;, quot;h3quot;);
req('POST', '/board/4815162342', callback, quot;move=g1-f3quot;);
// 200 OK; position =
// rnbqkbnr-pppp1ppp-8-4p3-4P3-5N2-PPPP1PPP-RNBQKB1R
42. John Maeda’s
Laws of Simplicity
Law 3: TIME
Savings in time feels like simplicity.
...ok, we need real-time
John Maeda @ http://lawsofsimplicity.com
44. But which Comet way?
Transport API
Long polling Socket
Forever Frame Publish/Subscribe
Script tags API based
WebSockets Data sync
Htmlfile REST?
Mime Messaging
Flash Remoting
Joe Walker @ http://www.slideshare.net/joewalker/comet-and-the-rise-of-highly-interactive-websites-presentation
45. HTTP Channels
is RESTful Comet
“The primary purpose of HTTP Channels
Kris Zyp: is to provide an application-level Comet
protocol for live data synchronization that
leverages the widely understood semantics
and vocabulary of HTTP/REST.”
Kris Zyp @ http://cometdaily.com/2008/06/05/intended-usage-of-http-channels/
46. Http Channels 2
POST /channels HTTP/1.1
Accept: application/http
X-Create-Client-Id: 123123
GET /foo HTTP/1.1
Accept: */*
X-Subscribe: *
X-Client-Id: 123123
PUT /foo HTTP/1.1
n
{ data: “foobar” }
HTTP/1.1 200 OK
X-Event: PUT
Content-Location: /foo
n
{ data: quot;foobarquot; }
Kris Zyp @ http://cometdaily.com/2008/05/13/http-channels-2/
47. Http Channels 3 X-Client-Id: 123123
POST /board/4815162342 HTTP/1.1
n
move = g1-f3
HTTP/1.1 200 OK
X-Event: POST
Content-Location: /board/4815162342
n
move = g1-f3
X-Client-Id: 124124 X-Client-Id: 125125 X-Client-Id: 126126
55. Continuous Deployment (testability)
Feature: change the position on board
Scenario: change position with a correct move
Given board with position wqd3,wkd1,bke8
When move to position wqd8,wkd1,bke8
Then response should be 201
And board should be in position wqd8,wkd1,bke8
Scenario: change position with a correct move
Given board with position wqd3,wkd1,bke8
When move to position wqd7,wkd1,bke8
Then response should be 403
And board should be in position wqd3,wkd1,bke8
56. Continuous Deployment (testability)
Scenario: change position with a correct move
Given board with position wqd3,wkd1,bke8
When move to position wqd8,wkd1,bke8
Then response should be 201
And board should be in position wqd8,wkd1,bke8
Given /^board with position (.+?)$/ do | from_position |
response = @client.post(quot;/boardquot;, quot;position = #{from_position}quot;)
response.status.should == 201
@board = response.header[quot;Locationquot;]
end
57. Continuous Deployment (testability)
Scenario: change position with a correct move
Given board with position wqd3,wkd1,bke8
When move to position wqd8,wkd1,bke8
Then response should be 201
And board should be in position wqd8,wkd1,bke8
When /^move to position (.+?)$/ do | to_position |
move_reponse = @client.post(@board, quot;position = #{to_position}quot;)
@move_response_status = move_response.status
end
58. Continuous Deployment (testability)
Scenario: change position with a correct move
Given board with position wqd3,wkd1,bke8
When move to position wqd8,wkd1,bke8
Then response should be 201
And board should be in position wqd8,wkd1,bke8
Then /^response should be (d{3})$/ do | expected_response_status |
@move_response_status.should == expected_response_status
end
59. Continuous Deployment (testability)
Scenario: change position with a correct move
Given board with position wqd3,wkd1,bke8
When move to position wqd8,wkd1,bke8
Then response should be 201
And board should be in position wqd8,wkd1,bke8
Then /^board should be in position (.+?)$/ do | expected_position |
current_position = @client.get(quot;#{@board}/positionquot;)
current_position.content.should == expected_position
end
60. Continuous Deployment (testability)
Feature: change the position on board
Scenario: change position with a correct move
Given board with position wqd3,wkd1,bke8
When move to position wqd8,wkd1,bke8
Then response should be 201
And board should be in position wqd8,wkd1,bke8
Scenario: change position with a correct move
Given board with position wqd3,wkd1,bke8
When move to position wqd7,wkd1,bke8
Then response should be 403
And board should be in position wqd3,wkd1,bke8
61. Continuous Deployment (testability)
coder@apollo ~/dev/cucumber/features $ cucumber change_position_on_board.feature
Feature: change the position on board
Scenario: change position with a correct move # change_position_on_board.feature:3
Given board with position wqd3,wkd1,bke8 # step_definitions/change_position_on_board_steps.rb:5
When move to position wqd8,wkd1,bke8 # step_definitions/change_position_on_board_steps.rb:9
Then response should be 201 # step_definitions/change_position_on_board_steps.rb:14
And board should be in position wqd8,wkd1,bke8 # step_definitions/change_position_on_board_steps.rb:19
Scenario: change position with a correct move # change_position_on_board.feature:9
Given board with position wqd3,wkd1,bke8 # step_definitions/change_position_on_board_steps.rb:5
When move to position wqd7,wkd1,bke8 # step_definitions/change_position_on_board_steps.rb:9
Then response should be 403 # step_definitions/change_position_on_board_steps.rb:14
And board should be in position wqd3,wkd1,bke8 # step_definitions/change_position_on_board_steps.rb:19
2 scenarios (2 passed)
8 steps (8 passed)
64. Continuous Deployment (testability)
We don’t care of
Position on board Model is already
is context (fixture) tested (mock)
// fixture // mock
var piece_square = quot;g1quot; var valid_moves_url = quot;/position/quot; + position +
var position = quot;/piece/quot; + piece_square +
quot;rnbqkbnr-pppp1ppp-8-4p3-4p3-8-PPPP1PPP-RNBQKBNRquot; quot;/movesquot;
var YAHOO.util.Connection.asyncRequest =
Chess.test.ServerMock([{
method: quot;GETquot;,
url: valid_moves_url,
response: {
code: 200
body: quot;moves = g1-e2, g1-f3, g1-h3quot;
}
}])
65. Continuous Deployment (testability)
new YAHOO.tool.TestCase({
name : quot;testMovequot;,
setUp: function() {
this.board = Chess.board();
this.board.setupPosition(position);
this.board.render(quot;mydivquot;);
},
tearDown: function() {
this.board.destroy();
}
test_highlightReachableSquares: function() {
var whiteKnight = this.board.pieceElementAt(piece_square);
YAHOO.util.UserAction.mousedown(whiteKnight);
this.wait(function(){
// for each g1, e2, f3, h3
YAHOO.util.Assert.isTrue(
YAHOO.util.Dom.hasClass(
this.board.squareElementAt(quot;g1quot;), quot;highlightquot;
);
);
}, 500);
}
}
67. Continuous Deployment (testability)
no assignment but Pattern Matching
1> X.
* 1: variable 'X' is unbound
2> X = 5.
5
3> X.
5
4> X = 6.
** exception error: no match of right hand side value 6
71. Continuous Deployment (scalability)
processes in Erlang are very cheap
1> processes:profileSpawnFor(1000).
Spawned 1000 processes in 10 (4) milliseconds
ok
2> processes:profileSpawnFor(10000).
Spawned 10000 processes in 96 (40) milliseconds
ok
3> processes:profileSpawnFor(100000).
Spawned 100000 processes in 884 (510) milliseconds
ok
75. Continuous Deployment (scalability)
factorials(Numbers) ->
map(fun(Number) ->
factorial(Number)
end, Numbers). Distributed on 20
different processes for
factorials(Numbers) -> each available nodes
on the cluster
pmap(fun(Number) ->
factorial(Number)
end, Numbers, 20, nodes()).
76. Continuous Deployment (hot-swap)
player:authorize(Request, Context). code to update
1> c(“/home/coder/upload/player.erl”). compile
2> code:load_file(player). and load
player:authorize(Request, Context). code updated
without
down-time
77. Continuous Deployment (hot-swap)
deploy(File) ->
{ ok, Module, Binary } = compile:file(File),
foreach(fun(Node) ->
rpc:call(Node, code, load_binary,
[ Module, File, Binary ]
)
end, nodes()). compile and deploy on
every node in the
cluster