Patterns, Paradigms, and Governance 2013-10-03

431 views

Published on

Scaling PHP
How patterns, paradigms, and governance can help you scale PHP performance and enable engineers contributing to your project

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
431
On SlideShare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
6
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Patterns, Paradigms, and Governance 2013-10-03

  1. 1. Scaling PHP Josh Levine josh@shapeways.com @heavypennies 1
  2. 2. WHAT IS SHAPEWAYS? 2
  3. 3. Shapeways 3 http://www.shapeways.com http://developers.shapeways.com http://shapejs.shapeways.com The worlds leading 3D printing marketplace and community
  4. 4. ARCHITECTURE 4
  5. 5. Architecture - System 5
  6. 6. Architecture - Framework 6 Road Runner
  7. 7. Architecture – Performance History 7
  8. 8. PATTERNS PARADIGMS GOVERNANCE 8
  9. 9. Patterns, Paradigms, and Governance 9 • How do these concepts help us scale PHP ? • Will I see concrete actionable examples ? • Will you show me some hardcore PHP h4x ?
  10. 10. • Patterns – code • Paradigms – knowledge • Governance – process 10
  11. 11. PATTERNS 11 Programatically enforced goodness
  12. 12. Patterns – Traits of Goodness 12 • Accessibility • Repeatability • Clear Rationale
  13. 13. Patterns - Accessibility 13 • An accessible pattern is one that is intuitive, documented, and when invoked, reads like natural language • Reading code that follows an accessible pattern is easier than reading code that does not follow
  14. 14. Patterns - Repeatability 14 • The repeatability of a pattern will ultimately decide its adoption • If I can copy and paste, or use a scaffold for a pattern, the pattern is repeatable and will proliferate itself throughout the code
  15. 15. Patterns – Clear Rationale 15 • You need to be able to explain why a pattern was chosen • All patterns have shortcomings – the *why* behind the pattern’s design and proliferation is critical in maintaining adherence
  16. 16. Pattern Examples: MVC 16 abstract class RoadRunnerController { $model = $this->getModel(); if($this->preHandle($model)) { $this->handleRequest($model); $this->postHandle($model); } $this->finalize($model); }
  17. 17. Pattern Examples: Auto-wiring 17 // Autowire the model manager public function preHandle($shapewaysModel, ModelManager $modelManager) { // do something with the ModelManager return parent::preHandle($shapewaysModel); } I can use any Manager in our domain model by adding it to my function signature.
  18. 18. Pattern Examples: Auto-wiring 18 public function invokeWithManagers($object, $function, $parameters) { $controllerClass = get_class($object); $function = new ReflectionMethod($controllerClass, $function); foreach ($function->getParameters() as $reflectionParameter) { $parameterClass = $reflectionParameter->getClass(); $parameterClassName = $parameterClass->getName(); // substr is much faster than pregmatch! if (substr($parameterClassName, -7) === "Manager") { $parameters[] = $this->instantiateManager($parameterClassName); } } return $function->invokeArgs($object, $parameters); }
  19. 19. PARADIGMS 19 Good things you need to know
  20. 20. 20 Paradigms – Traits of Goodness • Explicit • Consistent • Provide Clear Value
  21. 21. 21 Paradigms – Explicit A paradigm is explicit when the functionality exposed can be understood from the invoking side. Explicit paradigms show visibly throughout a codebase.
  22. 22. 22 Paradigms – Consistent A paradigm is consistent when it is applied consistently and everywhere applicable in the code. If your paradigm is only consistent in 60% of your code base, chances are high that folks will copy and proliferate code that violates the paradigm.
  23. 23. 23 Paradigms – Provide Clear Value It is important for the entire team to understand and agree on the value of a paradigm. Paradigms can easily feel like overhead - it is important to know *why* we choose to adhere to a paradigm.
  24. 24. Paradigm Examples - Constants $myObj->callFunction( ',', true, false, false ); Vs. $myObj->callFunction( MyObj::DELIMITER_COMMA, MyObj::MATCH_MULTIPLE, MyObj::LOG_RESULTS, MyObj::SKIP_DUPLICATES ); 24
  25. 25. Paradigm Examples – More Constants $_REQUEST["userId"] Vs. const REQUEST_USER_ID = "userId"; … $_REQUEST[self::REQUEST_USER_ID]; 25
  26. 26. Paradigm Examples - Consistent • Code Style • Enum/Lookup Tables • Parameter marshaling 26
  27. 27. Paradigm Examples – More Constants 27
  28. 28. Paradigm Examples – One to Many Making one query vs. two is often faster SELECT umf.id … , mfma.model_file_material_asset_id … FROM udesign_model_file umf LEFT JOIN model_file_material_asset mfma ON mfma.model_file_id = umf.id 28
  29. 29. Paradigm Examples – One to Many Generic function for mapping objects /** * Select an array of objects using the given EntityMapper * * @param $db the database link to use (read-only/read-write/etc) * @param $sql the query * @param $mapper EntityMapper * @return array */ public function selectObjects($db, $sql, $mapper) { $db = $this->getDbLink($db); $this->checkDBConnection($db); // Add backtrace information to the SQL as a comment // This helps immensely in slow query identification $sql = $this->prependURL($sql); if ($resultSet = $this->runQuery($sql, $db)) { while ($row = mysql_fetch_assoc($resultSet)) { $mapper->mapRow($row); } mysql_free_result($resultSet); } return $mapper->getResults(); } 29
  30. 30. Paradigm Examples – One to Many Mapping results follows a paradigm public function mapRow($row) { if (!isset($this->rows[$row['id']])) { $this->rows[$row['id']] = new ModelFileEntity( $row['id'] ); } $modelFile = $this->rows[$row['id']]; if (isset($row['model_file_material_asset_id'])) { $modelFileMaterialAsset = new ModelFileMaterialAsset( $row['model_file_material_asset_id'] ); $modelFile->addModelFileMaterialAsset($modelFileMaterialAsset); } } 30
  31. 31. Paradigm Examples – Caching Cache derived data public function getPrice() { if ($this->getPrice_cache !== NULL) return $this->getPrice_cache; // if override is set, use that if (($this->getPrice_cache = $this->getPriceOverride()) !== NULL) { return $this->getPrice_cache; } else { return ($this->getPrice_cache = $this->getPriceOriginal()); } } 31
  32. 32. Paradigm Examples – Caching Give control to the engineers public function getCurrencyById() { $cacheKey = 'currencyById-' . $currencyId . '-' . date(RoadRunnerDB::DATE_FORMAT_DAY); $currency = null; if(RoadRunnerLocalCache::get($cacheKey, $currency) === FALSE) { if (($currency = $this->memcacheGet($cacheKey, 0)) === FALSE) { $currency = $this->currencyDB->getcurrencyById($currencyId); $this->memcacheSet($cacheKey, $currency, 0); } RoadRunnerLocalCache::set($cacheKey, $currency); } return $currency; } 32
  33. 33. GOVERNANCE 33 For the good of all 
  34. 34. Governance Governance is the most difficult of all the goodness to achieve, and likely it is the most important for performance. If you can find a problem before it is live, you are 10x more likely to fix it before it impacts your users and your bottom line. 34
  35. 35. Governance Example – DB Query Review 35
  36. 36. Governance Example – DB Query Review 36
  37. 37. Governance Example – DB Query Review 37
  38. 38. Governance Example – Tracking 38
  39. 39. Governance Example – Tracking watch -n1 "cat rps_uri.sql | mysql tracking" 39
  40. 40. Governance Example – Tracking 40
  41. 41. Governance Example – Quality 41
  42. 42. THANK YOU 42

×