jhigginbotham64/Starlight.jl

Lock only once for multiple accesses

Closed this issue · 3 comments

As per our previous convo through discord, I have a proposal for reducing the number of times App needs to be locked for access to fields. Here it is:

struct Singleton
    # what's in here doesn't matter
    number::Int
    bool::Bool
    symbol::Symbol
    Singleton(; number::Int=0, bool::Bool=false, symbol::Symbol=:hi) = begin
        if !isassigned(singleton)
            singleton[] = new(number, bool, symbol)
        end
        
        return sng_lock, singleton
    end
end

global const singleton = Ref{Singleton}()
global const sng_lock = ReentrantLock()

# Locked Multiple Field Access Operator
function LMFAO(lk::ReentrantLock, objref::Base.RefValue{T}, fields::Symbol...) where T
    @assert typeof(lk) === ReentrantLock
    @lock lk let obj::T = objref[]
        stuff = NTuple{length(fields), Any}(getfield(obj, f) for f in fields)
    end
end

macro LMFAO(lk::Symbol, objref::Symbol, fields::Symbol...) 
    @info "Variable method"
    quote LMFAO($lk, $objref, $fields...) end
end

macro LMFAO(call::Expr, fields::Symbol...)
    @info "Call method"
    quote LMFAO(eval($call)..., $fields...) end 
end


n, b, sy = @LMFAO Singleton() number bool symbol # these don't have to be in order
@info n b sy

lk, sg = Singleton()
n, b, sy = @LMFAO lk sg number bool symbol
@info lk sg
@info n b sy

In theory this locks once to retrieve the struct and then the fields requested.
If the informality of the macro-acronym (macronym?) is too much I'll think of something else.

This seems like a neat idea, but I'm going to wait to work on it until I've settled how multi-app is going to be handled. Singletons should be going away in v0.3.0, so I don't want to invest too heavily in beautifying them just yet.

I intend to make a package called LockedStructs.jl that uses this and a couple other things pending, which you may be able to use. If all goes well it should be ready for the registry by the weekend.

I've been working on v0.3.0 and it's not done yet but already there are no more locks. Hence no need for this issue.