Skip to content

Commit

Permalink
fix tests and introduce locking
Browse files Browse the repository at this point in the history
  • Loading branch information
erdos committed Nov 16, 2023
1 parent acf9fab commit 3ba5397
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 36 deletions.
8 changes: 1 addition & 7 deletions java-src/io/github/erdos/stencil/PreparedFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,7 @@
public interface PreparedFragment extends AutoCloseable {

/**
* Implementation detail.
*/
@Deprecated
Object getImpl();

/**
* Makes the template clean up any resources allocated for it.
* Makes the template clean up resources allocated for it.
* <p>
* Subsequent invocations of this method have no effects. Rendering the template after this method call will throw
* an IllegalStateException.
Expand Down
10 changes: 6 additions & 4 deletions java-src/io/github/erdos/stencil/impl/LifecycleLock.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package io.github.erdos.stencil.impl;

import java.util.Collection;
import java.util.Objects;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Supplier;

public final class LifecycleLock implements AutoCloseable {

private final ReentrantReadWriteLock lock;
private final ReadWriteLock lock;
private final AtomicBoolean alive;
private final Runnable cleanup;

Expand All @@ -17,11 +19,11 @@ public LifecycleLock(Runnable cleanup) {
this.cleanup = Objects.requireNonNull(cleanup);
}

public <T> T run(Supplier<T> supplier) {
public <T> T execute(Callable<T> supplier) throws Exception {
lock.readLock().lock();
try {
if (alive.get()) {
return supplier.get();
return supplier.call();
} else {
throw new IllegalStateException("Component has already been closed.");
}
Expand Down
2 changes: 1 addition & 1 deletion src/stencil/model.clj
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@
(defn template-model->writers-map
"Evaluates a prepared template and returns a {path writer-fn} map that can be used to write the zip stream."
[template data function fragments]
(assert (map? data) (pr-str [:not-map data]))
(assert (map? data))
(-> template
(eval-template-model data function fragments)
(evaled-template-model->writers-map)))
Expand Down
45 changes: 22 additions & 23 deletions src/stencil/process.clj
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,11 @@
options {:only-includes (.isOnlyIncludes options)}
_ (with-open [zip-stream (io/input-stream template-file)]
(ZipHelper/unzipStreamIntoDirectory zip-stream zip-dir))
model (atom (model/load-template-model zip-dir options))
variables (TemplateVariables/fromPaths (get-variable-names @model) (get-fragment-names @model))
datetime (java.time.LocalDateTime/now)]
model (model/load-template-model zip-dir options)
variables (TemplateVariables/fromPaths (get-variable-names model) (get-fragment-names model))
datetime (java.time.LocalDateTime/now)
cleanup-fn #(FileHelper/forceDelete zip-dir)
lock (new io.github.erdos.stencil.impl.LifecycleLock cleanup-fn)]
(reify PreparedTemplate
(getTemplateFile [_] template-file)
(creationDateTime [_] datetime)

Check warning on line 45 in src/stencil/process.clj

View check run for this annotation

Codecov / codecov/patch

src/stencil/process.clj#L44-L45

Added lines #L44 - L45 were not covered by tests
Expand All @@ -46,18 +48,19 @@
;; TODO: use lifecycle lock here
(let [data (into {} (.getData data))
function (fn [name args] (.call function name (into-array Object args)))
writers-map (model/template-model->writers-map @model data function (update-vals fragments datafy))
writer (partial render-writers-map writers-map)]
fragments (update-vals fragments datafy)
all-locks (cons lock (keep ::lock (vals fragments)))
lock-wrapper (fn [f] ((reduce (fn [f lock] #(.execute lock f)) f all-locks)) ) ;; calls f wrapped in all locks
writers-map (lock-wrapper #(model/template-model->writers-map model data function fragments))]
(reify EvaluatedDocument
(write [_ target-stream]
;; TODO: use lifecycle lock here as well.<
(writer target-stream)))))
(close [_]
(reset! model nil)
(FileHelper/forceDelete zip-dir))
(lock-wrapper #(render-writers-map writers-map target-stream))))))
(close [_] (.close lock))
(getVariables [_] variables)
clojure.core.protocols/Datafiable
(datafy [_] @model))))
Object
(toString [_] (str "<PreparedTemplate of " template-file ">"))

Check warning on line 61 in src/stencil/process.clj

View check run for this annotation

Codecov / codecov/patch

src/stencil/process.clj#L61

Added line #L61 was not covered by tests
Datafiable
(datafy [_] model))))

;; Called from Java API
(defn prepare-fragment [^File fragment-file, ^PrepareOptions options]
Expand All @@ -67,17 +70,13 @@
options {:only-includes (.isOnlyIncludes options)}
_ (with-open [zip-stream (io/input-stream fragment-file)]
(ZipHelper/unzipStreamIntoDirectory zip-stream zip-dir))
model (atom (model/load-fragment-model zip-dir options))]
(reify PreparedFragment
(getImpl [_]
(or @model (throw (IllegalStateException. "Fragment has alrady been cleared."))))
(close [_]
(reset! model nil)
(FileHelper/forceDelete zip-dir))
Object
(toString [_] (str "<PreparedTemplate of " fragment-file ">"))
clojure.core.protocols/Datafiable
(datafy [_] @model))))
lock (new io.github.erdos.stencil.impl.LifecycleLock #(FileHelper/forceDelete zip-dir))
model (-> (model/load-fragment-model zip-dir options)
(assoc ::lock lock))]
(reify
PreparedFragment (close [_] (.close lock))
Object (toString [_] (str "<PreparedFragment of " fragment-file ">"))

Check warning on line 78 in src/stencil/process.clj

View check run for this annotation

Codecov / codecov/patch

src/stencil/process.clj#L78

Added line #L78 was not covered by tests
Datafiable (datafy [_] model))))

(defn- render-writers-map [writers-map outstream]
(assert (map? writers-map))
Expand Down
1 change: 0 additions & 1 deletion test/stencil/model_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

(deftest test-load-template-model
(let [model (datafy (api/prepare "test-resources/multipart/main.docx"))]
(println (type model) (type (datafy model)))
(is (contains? model :main))
(is (contains? model :content-types))

Expand Down

0 comments on commit 3ba5397

Please sign in to comment.