diff options
author | Shinya Maeda <shinya@gitlab.com> | 2018-04-26 10:30:27 +0300 |
---|---|---|
committer | Shinya Maeda <shinya@gitlab.com> | 2018-04-26 10:30:27 +0300 |
commit | f819bb7270979cb47a3f5ca97826c9491c983e4d (patch) | |
tree | ed643b5e879c0d84cc2fa213714e6739b523949c /app/models/ci/build_trace_chunk.rb | |
parent | c588dd843a6c68d0c10e5c447bfbe77ad7f3d9ea (diff) |
Optimize Trace#write/append/raw by caching data and avoiding unnecesary truncate
Diffstat (limited to 'app/models/ci/build_trace_chunk.rb')
-rw-r--r-- | app/models/ci/build_trace_chunk.rb | 62 |
1 files changed, 35 insertions, 27 deletions
diff --git a/app/models/ci/build_trace_chunk.rb b/app/models/ci/build_trace_chunk.rb index 794db48e1dc..9e7ebf41ee8 100644 --- a/app/models/ci/build_trace_chunk.rb +++ b/app/models/ci/build_trace_chunk.rb @@ -21,36 +21,14 @@ module Ci db: 2 } + ## + # Data is memoized for optimizing #size and #end_offset def data - if redis? - redis_data - elsif db? - raw_data - else - raise 'Unsupported data store' - end&.force_encoding(Encoding::BINARY) # Redis/Database return UTF-8 string as default - end - - def set_data(value) - raise ArgumentError, 'too much data' if value.bytesize > CHUNK_SIZE - - in_lock do - if redis? - redis_set_data(value) - elsif db? - self.raw_data = value - else - raise 'Unsupported data store' - end - - save! if changed? - end - - schedule_to_db if fullfilled? + @data ||= get_data end def truncate(offset = 0) - self.append("", offset) + self.append("", offset) if offset < size end def append(new_data, offset) @@ -58,7 +36,7 @@ module Ci raise ArgumentError, 'Offset is out of bound' if offset > current_data.bytesize || offset < 0 raise ArgumentError, 'Outside of chunk size' if CHUNK_SIZE < offset + new_data.bytesize - self.set_data(current_data.byteslice(0, offset) + new_data) + set_data(current_data.byteslice(0, offset) + new_data) end def size @@ -89,6 +67,36 @@ module Ci private + def get_data + if redis? + redis_data + elsif db? + raw_data + else + raise 'Unsupported data store' + end&.force_encoding(Encoding::BINARY) # Redis/Database return UTF-8 string as default + end + + def set_data(value) + raise ArgumentError, 'too much data' if value.bytesize > CHUNK_SIZE + + in_lock do + if redis? + redis_set_data(value) + elsif db? + self.raw_data = value + else + raise 'Unsupported data store' + end + + @data = value + + save! if changed? + end + + schedule_to_db if fullfilled? + end + def schedule_to_db return if db? |