From 8f665ae710b704188f423eb788e57ce95bfe82ef Mon Sep 17 00:00:00 2001 From: Stepan Strelets Date: Sat, 1 Apr 2017 23:45:00 +0300 Subject: [PATCH] Add build error writer (use bulk insert for improve performance) --- src/PHPCensor/Builder.php | 16 +++ src/PHPCensor/Model/Build.php | 24 ++--- src/PHPCensor/Model/Build/GithubBuild.php | 2 +- src/PHPCensor/Store/BuildErrorWriter.php | 117 ++++++++++++++++++++++ 4 files changed, 144 insertions(+), 15 deletions(-) create mode 100644 src/PHPCensor/Store/BuildErrorWriter.php diff --git a/src/PHPCensor/Builder.php b/src/PHPCensor/Builder.php index bc4fcd0c..72a95155 100644 --- a/src/PHPCensor/Builder.php +++ b/src/PHPCensor/Builder.php @@ -8,6 +8,7 @@ use PHPCensor\Logging\BuildLogger; use PHPCensor\Model\Build; use b8\Config; use b8\Store\Factory; +use PHPCensor\Store\BuildErrorWriter; use Psr\Log\LoggerAwareInterface; use Psr\Log\LoggerInterface; use Psr\Log\LogLevel; @@ -90,6 +91,11 @@ class Builder implements LoggerAwareInterface */ protected $buildLogger; + /** + * @var BuildErrorWriter + */ + private $buildErrorWriter; + /** * Set up the builder. * @@ -114,6 +120,7 @@ class Builder implements LoggerAwareInterface ); $this->interpolator = new BuildInterpolator(); + $this->buildErrorWriter = new BuildErrorWriter($this->build->getId()); } /** @@ -245,6 +252,7 @@ class Builder implements LoggerAwareInterface $this->build->removeBuildDirectory(); } + $this->buildErrorWriter->flush(); $this->store->save($this->build); } @@ -431,4 +439,12 @@ class Builder implements LoggerAwareInterface return $pluginFactory; } + + /** + * @return BuildErrorWriter + */ + public function getBuildErrorWriter() + { + return $this->buildErrorWriter; + } } diff --git a/src/PHPCensor/Model/Build.php b/src/PHPCensor/Model/Build.php index 5cd1c313..4bf2a830 100644 --- a/src/PHPCensor/Model/Build.php +++ b/src/PHPCensor/Model/Build.php @@ -3,6 +3,7 @@ namespace PHPCensor\Model; use PHPCensor\Builder; +use PHPCensor\Store\BuildErrorWriter; use Symfony\Component\Yaml\Parser as YamlParser; use PHPCensor\Model; use b8\Store\Factory; @@ -840,7 +841,6 @@ class Build extends Model * @param null $file * @param null $lineStart * @param null $lineEnd - * @return BuildError */ public function reportError( Builder $builder, @@ -851,19 +851,15 @@ class Build extends Model $lineStart = null, $lineEnd = null ) { - unset($builder); - - $error = new BuildError(); - $error->setBuild($this); - $error->setCreatedDate(new \DateTime()); - $error->setPlugin($plugin); - $error->setMessage($message); - $error->setSeverity($severity); - $error->setFile($file); - $error->setLineStart($lineStart); - $error->setLineEnd($lineEnd); - - return Factory::getStore('BuildError')->save($error); + $writer = $builder->getBuildErrorWriter(); + $writer->write( + $plugin, + $message, + $severity, + $file, + $lineStart, + $lineEnd + ); } /** diff --git a/src/PHPCensor/Model/Build/GithubBuild.php b/src/PHPCensor/Model/Build/GithubBuild.php index 63af9fe1..c2847269 100644 --- a/src/PHPCensor/Model/Build/GithubBuild.php +++ b/src/PHPCensor/Model/Build/GithubBuild.php @@ -222,7 +222,7 @@ class GithubBuild extends RemoteGitBuild } } - return parent::reportError($builder, $plugin, $message, $severity, $file, $lineStart, $lineEnd); + parent::reportError($builder, $plugin, $message, $severity, $file, $lineStart, $lineEnd); } /** diff --git a/src/PHPCensor/Store/BuildErrorWriter.php b/src/PHPCensor/Store/BuildErrorWriter.php new file mode 100644 index 00000000..496cd840 --- /dev/null +++ b/src/PHPCensor/Store/BuildErrorWriter.php @@ -0,0 +1,117 @@ +build_id = $build_id; + $this->buffer_size = max((int) $buffer_size, 1); + } + + /** + * Destructor + */ + public function __destruct() + { + $this->flush(); + } + + /** + * Write error + * @param string $plugin + * @param string $message + * @param int $severity + * @param string $file + * @param int $line_start + * @param int $line_end + * @param \DateTime $created_date + */ + public function write($plugin, $message, $severity, $file = null, $line_start = null, $line_end = null, $created_date = null) + { + if (is_null($created_date)) { + $created_date = new \DateTime(); + } + $this->errors[] = array( + 'plugin' => (string)$plugin, + 'message' => (string)$message, + 'severity' => (int)$severity, + 'file' => !is_null($file) ? (string)$file : null, + 'line_start' => !is_null($line_start) ? (int)$line_start : null, + 'line_end' => !is_null($line_end) ? (int)$line_end : null, + 'created_date' => $created_date->format('Y-m-d H:i:s'), + ); + if (count($this->errors) >= $this->buffer_size) { + $this->flush(); + } + } + + /** + * Flush buffer + */ + public function flush() + { + if (empty($this->errors)) { + return; + } + + $insert_values_placeholders = []; + $insert_values_data = []; + foreach ($this->errors as $i => $error) { + $insert_values_placeholders[] = '( + :build_id' . $i . ', + :plugin' . $i . ', + :file' . $i . ', + :line_start' . $i . ', + :line_end' . $i . ', + :severity' . $i . ', + :message' . $i . ', + :created_date' . $i . ' + )'; + $insert_values_data['build_id' . $i] = $this->build_id; + $insert_values_data['plugin' . $i] = $error['plugin']; + $insert_values_data['file' . $i] = $error['file']; + $insert_values_data['line_start' . $i] = $error['line_start']; + $insert_values_data['line_end' . $i] = $error['line_end']; + $insert_values_data['severity' . $i] = $error['severity']; + $insert_values_data['message' . $i] = $error['message']; + $insert_values_data['created_date' . $i] = $error['created_date']; + } + $query = ' + INSERT INTO {{build_error}} ( + {{build_id}}, + {{plugin}}, + {{file}}, + {{line_start}}, + {{line_end}}, + {{severity}}, + {{message}}, + {{created_date}} + ) + VALUES ' . join(', ', $insert_values_placeholders) . ' + '; + $stmt = Database::getConnection('write')->prepareCommon($query); + $stmt->execute($insert_values_data); + $this->errors = []; + } +}