summaryrefslogtreecommitdiffhomepage
path: root/lib/axlsx/rels/relationship.rb
diff options
context:
space:
mode:
authorVladimir Kochnev <[email protected]>2016-08-03 12:09:19 +0300
committerVladimir Kochnev <[email protected]>2019-10-02 18:06:35 +0300
commit913003eaf0456e4645cad91f2622354deae10841 (patch)
tree27293f11b37df246eaf15da6a062bbfade8882bb /lib/axlsx/rels/relationship.rb
parentc73b36d80f6a07862ead30a593f62b4797926110 (diff)
downloadcaxlsx-913003eaf0456e4645cad91f2622354deae10841.tar.gz
caxlsx-913003eaf0456e4645cad91f2622354deae10841.zip
Fix Relationship.instances cache.
This PR aims to fix several issues with Relationship cache: 1) It's not threadsafe, so I propose to use a TLS variable for this. 2) Memory obtained by cache remains non-freed before the next run of `serialize`. I think it should be freed immediately. 3) Memory should be freed in `ensure` block to prevent memory bloating in case of exception. *There are only two hard things in Computer Science: cache invalidation and naming things.*
Diffstat (limited to 'lib/axlsx/rels/relationship.rb')
-rw-r--r--lib/axlsx/rels/relationship.rb18
1 files changed, 13 insertions, 5 deletions
diff --git a/lib/axlsx/rels/relationship.rb b/lib/axlsx/rels/relationship.rb
index 99dad367..66f53b2a 100644
--- a/lib/axlsx/rels/relationship.rb
+++ b/lib/axlsx/rels/relationship.rb
@@ -8,20 +8,28 @@ module Axlsx
# Keeps track of all instances of this class.
# @return [Array]
def instances
- @instances ||= []
+ Thread.current[:axlsx_relationship_cached_instances] ||= []
end
-
- # Clear cached instances.
+
+ # Initialize cached instances.
#
# This should be called before serializing a package (see {Package#serialize} and
# {Package#to_stream}) to make sure that serialization is idempotent (i.e.
# Relationship instances are generated with the same IDs everytime the package
# is serialized).
+ def initialize_cached_instances
+ Thread.current[:axlsx_relationship_cached_instances] = []
+ end
+
+ # Clear cached instances.
+ #
+ # This should be called after serializing a package (see {Package#serialize} and
+ # {Package#to_stream}) to free the memory allocated for cache.
#
# Also, calling this avoids memory leaks (cached instances lingering around
# forever).
def clear_cached_instances
- @instances = []
+ Thread.current[:axlsx_relationship_cached_instances] = nil
end
# Generate and return a unique id (eg. `rId123`) Used for setting {#Id}.
@@ -30,7 +38,7 @@ module Axlsx
# {clear_cached_instances} will automatically reset the generated ids, too.
# @return [String]
def next_free_id
- "rId#{@instances.size + 1}"
+ "rId#{instances.size + 1}"
end
end