Our talk from RailsConf 2008 goes over our experience in large-scale enterprise applications, leaving the enterprise, and finding similar problems as indepedent consultants.
Interoperability and ecosystems: Assembling the industrial metaverse
Waxing Ballroom Floors on the Titanic
1. Just leave this up as
people filter in to the
room.
Bunk Monkey Start off panel with
“This really has no
bearing on anything. It’s
just here to give you a
taste of what’s to come
for the next 45 minutes.”
2. Just leave this up as
people filter in to the
room.
Bunk Monkey Start off panel with
“This really has no
bearing on anything. It’s
Spunk Monkey just here to give you a
taste of what’s to come
for the next 45 minutes.”
3. Just leave this up as
people filter in to the
room.
smegma
Bunk Monkey Start off panel with
“This really has no
bearing on anything. It’s
Spunk Monkey just here to give you a
taste of what’s to come
for the next 45 minutes.”
4. be sure to start the
meetronome at the
beginning.
Waxing Ballroom
Floors on the Titanic
and other less seaworthy vessels
OG Consulting
Kevin Barnes
Rick Bradley
Yossef Mendelssohn
14. t3h project: goals
Clinical system: 40,000+ patients / year
HIPAA, clinical trials, Sarbanes-Oxley
Full medical billing system
Share with 6-7 other large organizations
Common research community
Research-enabled clinical data
(t3h sinking ship)
15. t3h project: goals
Clinical system: 40,000+ patients / year
HIPAA, clinical trials, Sarbanes-Oxley
Full medical billing system
Share with 6-7 other large organizations
Common research community
Research-enabled clinical data
Save the world, yo
(t3h sinking ship)
17. t3h specs
we want the same
system as we currently
have, only AWESOME,
and OURS, so we can
prove to everyone we’re
the best in the world.
oh, and do some good.
(t3h sinking ship)
http://i160.photobucket.com/albums/t189/rossmcgrath16/redneck-mansion.jpg
18. please consult org chart
for portrait and name to
accompany statue. thx.
--t3h boss
What is expected
(t3h sinking ship)
19. What they want
(t3h sinking ship)
http://www.talendforge.org/wiki/doku.php?id=what_is_new1_1
22. so we push to meet with
the actual people who
supposedly know what
the business does and
wants
Meetings
(t3h sinking ship)
http://www.business-marketing.com/store/termination.html#5578
23. and, months later, when
we get meetings with
them, it’s a series of
months of meetings with
mostly Managers
(t3h sinking ship)
http://www.growingcoaches.com/webinar.htm
24. and if that’s not enough,
the CIO (who is a
consultant) sets up his
own Mega-Synergy Task
Force™
(t3h sinking ship)
http://www.brandascension.com/Elevation_Products.html
25. or “How to waste time
and demoralize people.”
(t3h sinking ship)
http://alternative-gifts.haluy.co.uk/product,details,,63e9efe53d8cd9167025f239b675592e.html
26. one way to make it clear
how much of a waste of
time meetings are is to
track them via
meetronome. compare with
the cost of the most recent
denied request for, say,
keyboards, wireless router,
non-paralyzing desk chairs,
etc.
show the running
meetronome now.
Be sure to quantify value
(t3h sinking ship)
27. The Enterprise Strikes Back
(t3h sinking ship)
http://www.startrekdesktopwallpaper.com/wallpapers/StarTrek_starship_Enterprise_NCC1701A_firing_phasers_freecomputerdesktop_wallpaper_1024.shtml
28. Perceived progress this was presented in
RailsConf 2006, some
snazzy unfolding left to
right, showing all the
things that were
improving
Rails
analysis patterns hire new developers
Rake
continuous integration
continuous integration migrations
nightly conversions switchtower getting more “Real”
svn
trac public svn
goodage
public trac
domain driven design wifi
public releases STI
unit tests
AJAX continuous builder
IRC
Postgres mac laptops
voluntary tickets
cvs auto deployments
stories
public IRC relocating
pair-on-demand
time
Oracle
assigned tickets 1,000 meetings
SQL schemae
suckage
Big Design Up Front
JUnit, etc.
JBoss
CruiseControl CTI
Ant
“deployments” lose technical lead
Java EJB3.0
Hibernate
for-profit partner
(t3h sinking ship)
29. The ice under the Titanic
goodage
time
wishful thinking by mgmt visionquests t3h webinar
Long-hidden incompetence
Budget padding
Blame Shifting Can’t-Do Attitude
Turf That Which Shall Not Be Named
suckage
Fear of Change
Ass-Covering
Croneyism
Finger-pointing
Old age and treachery
Corporate Politics
That Which Should Not Be
(t3h sinking ship)
30. Do your best
(t3h sinking ship)
http://www.sffringe.org/fringe06/06pix/sisyphus.jpg
31. Hiring
A great person is
available and you have 5
shitty people on your
team? No firing in t3h
enterprise.
that’s what she said
Hiring is purely about budgets and politics. A slot is open? Fill it with a
warm body. A great person is available? No slot, no hire.
that’s what she said
(t3h sinking ship)
34. 10 Interview Questions
For Developers
• How’s your test coverage?
• Oracle or SQLServer?
(t3h sinking ship)
35. 10 Interview Questions
For Developers
• How’s your test coverage?
• Oracle or SQLServer?
• Perforce or Bitkeeper?
(t3h sinking ship)
36. 10 Interview Questions
For Developers
• How’s your test coverage?
• Oracle or SQLServer?
• Perforce or Bitkeeper?
• Praise or Annotate?
(t3h sinking ship)
37. 10 Interview Questions
For Developers
• How’s your test coverage?
• Oracle or SQLServer?
• Perforce or Bitkeeper?
• Praise or Annotate?
• Java or PHP?
(t3h sinking ship)
38. 10 Interview Questions
For Developers
• How’s your test coverage?
• Oracle or SQLServer?
• Perforce or Bitkeeper?
• Praise or Annotate?
• Java or PHP?
• Singleton or Visitor?
(t3h sinking ship)
39. 10 Interview Questions
For Developers
• How’s your test coverage?
• Oracle or SQLServer?
• Perforce or Bitkeeper?
• Praise or Annotate?
• Java or PHP?
• Singleton or Visitor?
• Spolsky or Arrington?
(t3h sinking ship)
40. 10 Interview Questions
For Developers
• How’s your test coverage?
• Oracle or SQLServer?
• Perforce or Bitkeeper?
• Praise or Annotate?
• Java or PHP?
• Singleton or Visitor?
• Spolsky or Arrington?
• Have you implemented final, destructors, or xdoclet in Ruby?
(t3h sinking ship)
41. 10 Interview Questions
For Developers
• How’s your test coverage?
• Oracle or SQLServer?
• Perforce or Bitkeeper?
• Praise or Annotate?
• Java or PHP?
• Singleton or Visitor?
• Spolsky or Arrington?
• Have you implemented final, destructors, or xdoclet in Ruby?
• Have you ever written an empty if just to use the else?
(t3h sinking ship)
42. 10 Interview Questions
For Developers
• How’s your test coverage?
• Oracle or SQLServer?
• Perforce or Bitkeeper?
• Praise or Annotate?
• Java or PHP?
• Singleton or Visitor?
• Spolsky or Arrington?
• Have you implemented final, destructors, or xdoclet in Ruby?
• Have you ever written an empty if just to use the else?
• Who owns the code?
(t3h sinking ship)
43. 10 Interview Questions
For Sysadmins
“Puppet or Cfengine” may
be the only question
with a right answer
(t3h sinking ship)
44. 10 Interview Questions
For Sysadmins
• What’s your deployment process?
“Puppet or Cfengine” may
be the only question
with a right answer
(t3h sinking ship)
45. 10 Interview Questions
For Sysadmins
• What’s your deployment process?
• Security or Availability?
“Puppet or Cfengine” may
be the only question
with a right answer
(t3h sinking ship)
46. 10 Interview Questions
For Sysadmins
• What’s your deployment process?
• Security or Availability?
• XP or Vista?
“Puppet or Cfengine” may
be the only question
with a right answer
(t3h sinking ship)
47. 10 Interview Questions
For Sysadmins
• What’s your deployment process?
• Security or Availability?
• XP or Vista?
• Oracle or SQLServer?
“Puppet or Cfengine” may
be the only question
with a right answer
(t3h sinking ship)
48. 10 Interview Questions
For Sysadmins
• What’s your deployment process?
• Security or Availability?
• XP or Vista?
• Oracle or SQLServer?
• Java or Perl?
“Puppet or Cfengine” may
be the only question
with a right answer
(t3h sinking ship)
49. 10 Interview Questions
For Sysadmins
• What’s your deployment process?
• Security or Availability?
• XP or Vista?
• Oracle or SQLServer?
• Java or Perl?
• ksh or tcsh?
“Puppet or Cfengine” may
be the only question
with a right answer
(t3h sinking ship)
50. 10 Interview Questions
For Sysadmins
• What’s your deployment process?
• Security or Availability?
• XP or Vista?
• Oracle or SQLServer?
• Java or Perl?
• ksh or tcsh?
•
“Puppet or Cfengine” may
Ant or Maven? be the only question
with a right answer
(t3h sinking ship)
51. 10 Interview Questions
For Sysadmins
• What’s your deployment process?
• Security or Availability?
• XP or Vista?
• Oracle or SQLServer?
• Java or Perl?
• ksh or tcsh?
•
“Puppet or Cfengine” may
Ant or Maven? be the only question
with a right answer
• ports or yum?
(t3h sinking ship)
52. 10 Interview Questions
For Sysadmins
• What’s your deployment process?
• Security or Availability?
• XP or Vista?
• Oracle or SQLServer?
• Java or Perl?
• ksh or tcsh?
•
“Puppet or Cfengine” may
Ant or Maven? be the only question
with a right answer
• ports or yum?
• Puppet or Cfengine?
(t3h sinking ship)
53. 10 Interview Questions
For Sysadmins
• What’s your deployment process?
• Security or Availability?
• XP or Vista?
• Oracle or SQLServer?
• Java or Perl?
• ksh or tcsh?
•
“Puppet or Cfengine” may
Ant or Maven? be the only question
with a right answer
• ports or yum?
• Puppet or Cfengine?
• CI?
(t3h sinking ship)
55. Transparency
Be 100% transparent
(t3h sinking ship)
http://www.brianmicklethwait.com/index.php/weblog/computer_transparency/
56. Transparency
Publicizing your transparency means never having to answer the
question: “Why didn’t I know about this?”
(t3h sinking ship)
http://drinkingliberally.org/blogs/idahofalls/archives/2007/02/his_head_will_g.html
61. Mr. Cant Chart
(t3h sinking ship)
http://www.flickr.com/photos/atmos/217012352/
62. t3h Cant Chart
• Identify all the tasks
that you are
responsible for.
(t3h sinking ship)
63. t3h Cant Chart
• Plot out what
depends on what.
(t3h sinking ship)
64. t3h Cant Chart
• From those tasks, find
the CANT™ – who
is holding up the
works, and what are
their excuses.
• A task can have many
CANTs.
• Tally the CANTs.
(t3h sinking ship)
65. t3h Cant Chart
• Separate the tasks
you will do from
those with CANTs.
(t3h sinking ship)
66. t3h Cant Chart
• Apply the secret
sauce CANT formula.
• The big tasks are
where you need to
be focused.
• Your enemies are
those jerks with the
highest CANT
scores.
(t3h sinking ship)
67. t3h Cant Chart
• You either won or
failed hardcore.
(t3h sinking ship)
70. 10 Interview Questions
For the company
• How’s your test coverage?
• Oracle or SQLServer?
(t3h sinking ship)
71. 10 Interview Questions
For the company
• How’s your test coverage?
• Oracle or SQLServer?
• FogBugz or Excel?
(t3h sinking ship)
72. 10 Interview Questions
For the company
• How’s your test coverage?
• Oracle or SQLServer?
• FogBugz or Excel?
• What’s your deployment process?
(t3h sinking ship)
73. 10 Interview Questions
For the company
• How’s your test coverage?
• Oracle or SQLServer?
• FogBugz or Excel?
• What’s your deployment process?
• What’s your HR department like?
(t3h sinking ship)
74. 10 Interview Questions
For the company
• How’s your test coverage?
• Oracle or SQLServer?
• FogBugz or Excel?
• What’s your deployment process?
• What’s your HR department like?
• Who owns the code?
(t3h sinking ship)
75. 6
10 Interview Questions
For the company
• How’s your test coverage?
• Oracle or SQLServer?
• FogBugz or Excel?
• What’s your deployment process?
• What’s your HR department like?
• Who owns the code?
(t3h sinking ship)
76. Plowing a new field
Donald Miralle/Getty Images, http://recipes.howstuffworks.com/salt5.htm
77. this is Karl, or a we call him
Karlsbad (at testing)
Any code can be legacy code
78. Legacy Code
def associate( association, options = {} )
return false unless association &&
association.account_id == self.account_id &&
association.uniq_id != self.uniq_id
options = { :update_record => true }.merge( options )
self.associations.each do |a|
if association.uniq_id == a.uniq_id
return false
end
end
associations << association
self.save_with_validation false
association.associate( self, :update_record => false )
self.save_with_validation false
if options[:update_record]
if self.record
self.record.update_build() if self.record
else
self.record = Record.build_with self
end
end
end
(Legacy Code)
80. Characterization Tests
class RecursiveMock
def initialize(args = {})
@stubs = {}.merge(args)
end
def method_missing(meth, *args)
if @stubs.has_key?(meth.to_sym)
return @stubs[meth.to_sym]
end
self
end
end
(Legacy Code)
82. Characterization Tests
describe YourMom do
before :each { @your_mom = YourMom.new }
currently quot;is at my housequot; do
@your_mom.should be_at_my_house
end
describe quot;when at my housequot; do
before :each do
@your_mom.stubs(:at_my_house?).returns(true)
end
she quot;should take the bus homequot;
end
end
(Legacy Code)
83. Characterization Tests
YourMom
- *** CURRENTLY *** is at my house
YourMom when at my house
- should take the bus home (PENDING: Not Yet Implemented)
Pending:
YourMom when at my house should take the bus home (Not
Yet Implemented)
Finished in 0.174782 seconds
2 examples, 0 failures, 1 pending
(Legacy Code)
84. Characterization Tests
currently quot;has a summary which includes the amount truncated to dollarsquot; do
@payment.stubs(:account).returns(stub('acct', :name => 'acct 1'))
@payment.amount_in_cents = 1234
@payment.summary.should match(/$12b/)
end
currently quot;has a summary which fails if payment amount is not setquot; do
@payment.stubs(:account).returns(stub('acct', :name => 'acct 1'))
@payment.amount_in_cents = nil
lambda { @payment.summary }.should raise_error
end
(Legacy Code)
92. Feedback
• Cruisecontrol.rb; flog, heckle,
flame; Use EC2 or slices if
needed; Do short iterations,
perform post-mortems
(feedback loops)
http://www.etsu.edu/philos/classes/rk/postmodern/htmdescriptionpages/30paik2desc.jpg
104. Object Daddy
class Category < ActiveRecord::Base
has_many :items
validates_presence_of :name
validates_uniqueness_of :name
end
class Item < ActiveRecord::Base
belongs_to :category
validates_presence_of :category
validates_presence_of :code
validates_uniqueness_of :code
validates_format_of :code, :with => /^[a-zA-Z]+-d+$/
end
Models
(rails == wrong)
105. Object Daddy
class Category < ActiveRecord::Base
has_many :items
validates_presence_of :name
validates_uniqueness_of :name
end
Model
class Category
generator_for :name, :start => 'test' do |prev|
prev.succ
end
end
Exemplar
(rails == wrong)
106. Object Daddy
class Item < ActiveRecord::Base
belongs_to :category
validates_presence_of :category
validates_presence_of :code
validates_uniqueness_of :code
validates_format_of :code, :with => /^[a-zA-Z]+-d+$/
end
Model
class Item
generator_for :code, :start => 'test-001' do |prev|
prefix, number = prev.split('-')
[prefix, number.succ].join('-')
end
end
Exemplar
(rails == wrong)
107. Object Daddy
some unexpected
problems came up while
making this slide.
Loading development environment (Rails 2.0.2)
OD is intended for use in
>> tests, not the console.
This is just an example
for illumination.
It’s kind of difficult to
write tests for how
something works in a
non-test setting.
(rails == wrong)
108. Object Daddy
some unexpected
problems came up while
making this slide.
Loading development environment (Rails 2.0.2)
OD is intended for use in
>> Category.generate tests, not the console.
=> #<Category id: 26, name: quot;testquot;> This is just an example
for illumination.
>>
It’s kind of difficult to
write tests for how
something works in a
non-test setting.
(rails == wrong)
109. Object Daddy
some unexpected
problems came up while
making this slide.
Loading development environment (Rails 2.0.2)
OD is intended for use in
>> Category.generate tests, not the console.
=> #<Category id: 26, name: quot;testquot;> This is just an example
for illumination.
>> Category.generate
It’s kind of difficult to
=> #<Category id: 27, name: quot;tesuquot;> write tests for how
>> something works in a
non-test setting.
(rails == wrong)
110. Object Daddy
some unexpected
problems came up while
making this slide.
Loading development environment (Rails 2.0.2)
OD is intended for use in
>> Category.generate tests, not the console.
=> #<Category id: 26, name: quot;testquot;> This is just an example
for illumination.
>> Category.generate
It’s kind of difficult to
=> #<Category id: 27, name: quot;tesuquot;> write tests for how
>> Item.generate something works in a
non-test setting.
=> #<Item id: 4, code: quot;test-001quot;, category_id: 28>
>>
(rails == wrong)
111. Object Daddy
some unexpected
problems came up while
making this slide.
Loading development environment (Rails 2.0.2)
OD is intended for use in
>> Category.generate tests, not the console.
=> #<Category id: 26, name: quot;testquot;> This is just an example
for illumination.
>> Category.generate
It’s kind of difficult to
=> #<Category id: 27, name: quot;tesuquot;> write tests for how
>> Item.generate something works in a
non-test setting.
=> #<Item id: 4, code: quot;test-001quot;, category_id: 28>
>> cat = Category.find :first
=> #<Category id: 26, name: quot;testquot;>
>> cat.items.generate
=> #<Item id: 5, code: quot;test-002quot;, category_id: 26>
>>
(rails == wrong)
112. Object Daddy
some unexpected
problems came up while
making this slide.
Loading development environment (Rails 2.0.2)
OD is intended for use in
>> Category.generate tests, not the console.
=> #<Category id: 26, name: quot;testquot;> This is just an example
for illumination.
>> Category.generate
It’s kind of difficult to
=> #<Category id: 27, name: quot;tesuquot;> write tests for how
>> Item.generate something works in a
non-test setting.
=> #<Item id: 4, code: quot;test-001quot;, category_id: 28>
>> cat = Category.find :first
=> #<Category id: 26, name: quot;testquot;>
>> cat.items.generate
=> #<Item id: 5, code: quot;test-002quot;, category_id: 26>
>> Category.generate(:name => 'things')
=> #<Category id: 29, name: quot;thingsquot;>
>>
(rails == wrong)
113. Object Daddy
some unexpected
problems came up while
making this slide.
Loading development environment (Rails 2.0.2)
OD is intended for use in
>> Category.generate tests, not the console.
=> #<Category id: 26, name: quot;testquot;> This is just an example
for illumination.
>> Category.generate
It’s kind of difficult to
=> #<Category id: 27, name: quot;tesuquot;> write tests for how
>> Item.generate something works in a
non-test setting.
=> #<Item id: 4, code: quot;test-001quot;, category_id: 28>
>> cat = Category.find :first
=> #<Category id: 26, name: quot;testquot;>
>> cat.items.generate
=> #<Item id: 5, code: quot;test-002quot;, category_id: 26>
>> Category.generate(:name => 'things')
=> #<Category id: 29, name: quot;thingsquot;>
>> Category.generate
=> #<Category id: 30, name: quot;teswquot;>
(rails == wrong)
124. The if expression
- evaluates body if expression is true
- does not evaluate body if expression is false
- does not evaluate else-body if expression is true
- evaluates only else-body if expression is false
- returns result of then-body evaluation if expression is true
- returns result of last statement in then-body if expression is true
or Trustworthy
138. What has OG done for me lately?
• object_daddy
•
Check it out on github
timely user: flogic
• shmemeter
• autochronic
• freshtrack
• nihilist_bot (& http://ni.hili.st/)
• ultrasphinx_search_wrapper
• flame (aka flog w/ tests & blame)