From dc28a7547e44bb41febdcab6b081a54d7c6fdb45 Mon Sep 17 00:00:00 2001
From: rafaqz <rafaelschouten@gmail.com>
Date: Fri, 4 Feb 2022 03:19:50 +0100
Subject: [PATCH] a bit more type stability

---
 Project.toml         | 13 ++++++++
 src/AssetRegistry.jl | 77 ++++++++++++++++++--------------------------
 2 files changed, 45 insertions(+), 45 deletions(-)
 create mode 100644 Project.toml

diff --git a/Project.toml b/Project.toml
new file mode 100644
index 0000000..4504457
--- /dev/null
+++ b/Project.toml
@@ -0,0 +1,13 @@
+name = "AssetRegistry"
+uuid = "bf4720bc-e11a-5d0c-854e-bdca1663c893"
+license = "MIT"
+version = "0.1.0"
+
+[deps]
+JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
+Pidfile = "fa939f87-e72e-5be4-a000-7fc836dbe307"
+SHA = "ea8e919c-243c-51af-8825-aaa63cd721ce"
+
+[compat]
+JSON = "0.21, 1.0"
+Pidfile = "1.2.0"
diff --git a/src/AssetRegistry.jl b/src/AssetRegistry.jl
index 9f392f1..0be57b3 100644
--- a/src/AssetRegistry.jl
+++ b/src/AssetRegistry.jl
@@ -26,9 +26,8 @@ julia> key = AssetRegistry.register("/Users/ranjan/.julia/v0.6/Tachyons/assets/t
 ```
 """
 function register(path; registry_file = joinpath(homedir(), ".jlassetregistry.json"))
-    target = normpath(abspath(expanduser(path)))
-    (isfile(target) || isdir(target)) ||
-                    error("Asset not found")
+    target = gettarget(path)
+    (isfile(target) || isdir(target)) || error("Asset not found")
 
     key = getkey(target)
     if haskey(registry, key)
@@ -37,71 +36,57 @@ function register(path; registry_file = joinpath(homedir(), ".jlassetregistry.js
     end
 
     # update global registry file
-
-    # touch(registry_file) -- this doesn't work on Azure fs
-    if !isfile(registry_file)
-        # WARN: may need a lock here
-        open(_->nothing, registry_file, "w")
-    end
-
-    pidlock = joinpath(homedir(), ".jlassetregistry.lock")
-
-    withlock(pidlock) do
-        fkey = filekey(key)
-        io = open(registry_file, "r+") # open in read-and-write mode
-        # first get existing entries
-        prev_registry =  filesize(io) > 0 ? JSON.parse(io) : Dict{String,Tuple{String,Int}}()
-
+    update_registry_file(registry_file, key) do prev_registry, fkey
         if haskey(prev_registry, fkey)
-            prev_registry[fkey] = (target, prev_registry[fkey][2]+1) # increment ref count
+            prev_registry[fkey] = [target, prev_registry[fkey][2]+1] # increment ref count
         else
-            prev_registry[fkey] = (target, 1) # init refcount to 1
+            prev_registry[fkey] = [target, 1] # init refcount to 1
         end
-
-        # write the updated registry to file
-        seekstart(io)
-        JSON.print(io, prev_registry)
-
-        # truncate it to current length
-        truncate(io, position(io))
-        close(io)
     end
 
     registry[key] = target # keep this in current process memory
 
-
-    key
+    return key
 end
 
 function deregister(path; registry_file = joinpath(homedir(), ".jlassetregistry.json"))
-    target = normpath(abspath(expanduser(path)))
+    target = gettarget(path)
 
     key = getkey(target)
     if !haskey(registry, key)
-        return
+        return nothing
     end
-
     pop!(registry, key)
 
-    touch(registry_file)
-
-    pidlock = joinpath(homedir(), ".jlassetregistry.lock")
-    withlock(pidlock) do
-        fkey = filekey(key)
-        io = open(registry_file, "r+")
-
-        # get existing information
-        prev_registry =  filesize(io) > 0 ? JSON.parse(io) : Dict{String,Tuple{String, Int}}()
-
+    update_registry_file(registry_file, key) do prev_registry, fkey
         if haskey(prev_registry, fkey)
             val, count = prev_registry[fkey]
             if count == 1
                 pop!(prev_registry, fkey)
             else
-                prev_registry[fkey] = (val, count-1) # increment ref count
+                prev_registry[fkey] = [val, count-1] # increment ref count
             end
         end
+    end
+
+    return key
+end
 
+function update_registry_file(f, file, key)
+    pidlock = joinpath(homedir(), ".jlassetregistry.lock")
+    # touch(registry_file) -- this doesn't work on Azure fs
+    if !isfile(file)
+        # WARN: may need a lock here
+        open(_ -> nothing, file, "w")
+    end
+    withlock(pidlock) do
+        fkey = filekey(key)
+        io = open(file, "r+")
+        # get existing information
+        DT = Dict{String,Vector{Union{String,Int}}}
+        prev_registry =  filesize(io) > 0 ? JSON.parse(io) : DT()
+        f(prev_registry, fkey)
+        # write the updated registry to file
         seekstart(io)
         JSON.print(io, prev_registry)
 
@@ -110,9 +95,11 @@ function deregister(path; registry_file = joinpath(homedir(), ".jlassetregistry.
         close(io)
     end
 
-    key
+    return key
 end
 
+gettarget(path) = normpath(abspath(expanduser(path)))
+
 getkey(path) =  baseurl[] * "/assetserver/" * bytes2hex(sha1(abspath(path))) * "-" * basename(path)
 
 isregistered(path) = haskey(registry, getkey(path))