Search code examples
clojurejgrapht

How to guard a mutable object against concurrent read/write access in Clojure?


I'm using jgrapht, a graph library for java as the backbone of my graph operations. It mutates its state on every change, like adding or removing an edge or a vertex.

I'm accessing this "object" from multiple threads / go-loops.

I've started naively wrapping the graph object with an atom but as far as I understand, it doesn't protect (and can't do) against directly changing the state of its content. Its a safeguard only if you are able to use reset! or swap! functions.

I've changed to refs and started doing my mutations in dosync blocks but I still notice some weird behaviour from time to time. They are hard to pinpoint since they appear on runtime. As you would expect.

I'm not experienced in Clojure ecosystem, so I'd appreciate if you can point me into a couple of alternative strategies for dealing with stateful objects from Java in Clojure.

PS: I'm aware of loom and would love to use it, but it lacks for my most important requirement: finding all simple cycles in a weighted directed graph with negative weights.


Solution

  • Just a note that we recently received a contribution of AsSynchronizedGraph in JGraphT:

    https://github.com/jgrapht/jgrapht/blob/master/jgrapht-core/src/main/java/org/jgrapht/graph/concurrent/AsSynchronizedGraph.java

    It allows you to protect a graph with a wrapper which uses a ReadWriteLock. There are a bunch of usage caveats in the Javadoc.

    It's not released yet, but it's available in the latest SNAPSHOT build.