Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Pragmatic Lessons of Rails & Ruby in the Enterprise

475 views

Published on

Slides for the RailsConf 2016 talk Pragmatic Lessons of Rails & Ruby in the Enterprise.

Published in: Software
  • Be the first to comment

  • Be the first to like this

Pragmatic Lessons of Rails & Ruby in the Enterprise

  1. 1. Pragmatic Lessons of Rails & Ruby in the Enterprise Nathan Beyer Cerner, Senior Principal Architect & Distinguished Engineer
  2. 2. Health care is too important to stay the same
  3. 3. Nathan Beyer • @nbeyer • A Cerner associate for 17 years • Working on open source before it was cool • Aging hipster
  4. 4. A brief history of web application development at Cerner …
  5. 5. 1995 2020
  6. 6. 1995 2020 C++, ASP
  7. 7. Party like it’s 1999 STDMETHODIMP  CEventSetSearch::Show(IUnknown  *  pUnkOb)   {      AFX_MANAGE_STATE(AfxGetStaticModuleState())   MsgWriteF  (MSG_DEFAULT,  eMsgLog_Commit,  _T("WebFlowsheet"),  eMsgLvl_Debug,   _T("CEventSetSearch::Show()"));      try      {          IFlowsheetOb  *pOb  =  (IFlowsheetOb  *)pUnkOb;          BSTR  bstrKey,fsobKey;          CString  theKey,  thefsobKey;          pOb-­‐>GetKey  (&bstrKey);          theKey  =  bstrKey;          pOb-­‐>GetFSOBKey  (&fsobKey);          thefsobKey  =  fsobKey;                    m_piResponse-­‐>Write  (CComVariant  ("<BODY>n"));          m_piResponse-­‐>Write  (CComVariant  (_T("<FORM  METHOD=POST  ACTION="../ WebPowerChartASP/PVFSEventSetSearch.asp?key=")));          m_piResponse-­‐>Write  (CComVariant  (theKey));          m_piResponse-­‐>Write  (CComVariant  ("&fsobKey="));          m_piResponse-­‐>Write  (CComVariant  (thefsobKey));          m_piResponse-­‐>Write  (CComVariant  ("&FunctionInd=SHOWRESULTS"  TARGET= "EVENTSETRESULTS">n"));                    m_piResponse-­‐>Write  (CComVariant  (_T("<TABLE  CELLSPACING=0  CLASS= "PVFSEventSetSearchTable">n")));          m_piResponse-­‐>Write  (CComVariant  (_T("<TR><TD  CLASS= "PVFSEventSetSearchTableData">Procedure:</TD>n")));          m_piResponse-­‐>Write  (CComVariant  (_T("<TD  CLASS= "PVFSEventSetSearchTableData">")));          m_piResponse-­‐>Write  (CComVariant  (_T("<INPUT  TYPE=BUTTON  NAME="OriginalBtn "  VALUE="Return  to  Original"  onClick="refreshFrame(self.parent,'../ WebPowerChartASP/pvfssearchcriteriaupd.asp?key=")));          m_piResponse-­‐>Write  (CComVariant  (theKey));          m_piResponse-­‐>Write  (CComVariant  ("&fsobKey="));          m_piResponse-­‐>Write  (CComVariant  (thefsobKey));          m_piResponse-­‐>Write  (CComVariant   (_T("&NewEventSet=0&FunctionInd=NEWEVENTSET');"></TD>n")));          m_piResponse-­‐>Write  (CComVariant  (_T("<TR>n")));          m_piResponse-­‐>Write  (CComVariant  (_T("<TD  CLASS= "PVFSEventSetSearchTableData"><INPUT  TYPE=TEXT  NAME="SearchText"  SIZE= "25"></TD>n")));          m_piResponse-­‐>Write  (CComVariant  (_T("<TD  CLASS= "PVFSEventSetSearchTableData"><INPUT  TYPE=SUBMIT  NAME="SearchBtn"  VALUE= "Search">  ")));          m_piResponse-­‐>Write  (CComVariant  (_T("<INPUT  TYPE=BUTTON  NAME="CancelBtn"   VALUE="Cancel"  onClick="refreshFrame(self.parent,'../WebPowerChartASP/ pvfssearchcriteriaupd.asp?key=")));          m_piResponse-­‐>Write  (CComVariant  (theKey));          m_piResponse-­‐>Write  (CComVariant  ("&fsobKey="));          m_piResponse-­‐>Write  (CComVariant  (thefsobKey));          m_piResponse-­‐>Write  (CComVariant  (_T("&FunctionInd=CANCEL');"></TD>n")));          m_piResponse-­‐>Write  (CComVariant  (_T("</TR>n")));          m_piResponse-­‐>Write  (CComVariant  (_T("</TABLE>n</FORM>")));          m_piResponse-­‐>Write  (CComVariant  ("</BODY>n"));      }      catch(...)      {          MsgWriteF  (MSG_DEFAULT,  eMsgLog_Commit,  _T("WebFlowsheet"),                eMsgLvl_Warning,  _T("Exception:  CEventSetSearch::Show()"));      }      return  S_OK;   }
  8. 8. 1995 2020 C++, ASP
  9. 9. 1995 2020 C++, ASP Java, Struts
  10. 10. 1995 2020 C++, ASP Java, Struts Python, Django
  11. 11. 1995 2020 C++, ASP Java, Struts Python, Django Ruby, Rails
  12. 12. 1995 2020 C++, ASP Java, Struts Python, Django Ruby, Rails iOS, Rails, Thrift, Chef
  13. 13. 1995 2020 C++, ASP Java, Struts Python, Django Ruby, Rails iOS, Rails, Thrift, Chef Blue Steel, Rails, JAX-RS, Chef
  14. 14. Seemingly unique concerns
  15. 15. A component of a distributed system
  16. 16. A component of a distributed system JAX-RSJAX-RS JAX-RSJAX-RS MySQL Here be big data
  17. 17. https://www.flickr.com/photos/27452744@N08/3104979764/ Keep it secure
  18. 18. User event auditing
  19. 19. Federated authentication
  20. 20. Group & Data-based Access Control
  21. 21. https://www.flickr.com/photos/usfwspacific/5565696408/ Development Ecosystem
  22. 22. Gem management https://www.flickr.com/photos/jessa1155/5263646949
  23. 23. Builds https://www.flickr.com/photos/pasukaru76/6893926948
  24. 24. Builds • Tagged, Packaged, Tested https://www.flickr.com/photos/pasukaru76/6893926948
  25. 25. Builds • Tagged, Packaged, Tested • Evidence archived https://www.flickr.com/photos/pasukaru76/6893926948
  26. 26. Builds • Tagged, Packaged, Tested • Evidence archived • Roll Out - pluggable tool for Ruby- based projects https://www.flickr.com/photos/pasukaru76/6893926948
  27. 27. Dependencies
  28. 28. Dependencies • Always stay up-to-date
  29. 29. Dependencies • Always stay up-to-date • Minimize dependencies
  30. 30. Dependencies • Always stay up-to-date • Minimize dependencies • Vetting process
  31. 31. Some lessons
  32. 32. Beware Culture Shock class  ServiceFactory          private          @@_service_interface  =  nil          def  initialize()          end      public              #  Get  an  instance  of  the  Service  handler.          def  self.get_service              if  (@@_service_interface.absent?)                  @@_service_interface  =  Service.new();              end              @@_service_interface          end   end
  33. 33. Dynamic typing fear https://www.flickr.com/photos/francoiskarm/17178127529
  34. 34. Misconceptions of reuse
  35. 35. Misconceptions of reuse • Microframeworks
  36. 36. Misconceptions of reuse • Microframeworks • Abstracting the abstractions
  37. 37. Misconceptions of reuse • Microframeworks • Abstracting the abstractions • DRY is overrated at scale
  38. 38. Questions!?
  39. 39. Connect https://engineering.cerner.com @CernerEng Cerner Social Tonight, 7-9PM @ No Other Pub, Power & Light Cerner Booth Raffle for DJI Phantom Drone, Jack Stack Gift Card

×