Problem
When Runway loads a record, it replaces each collection field with a
plain ArrayList (or LinkedHashSet), discarding any thread-safe
collection the field was initialized with. A field declared as, for
example, Collections.synchronizedList(...) or a CopyOnWriteArrayList
is therefore thread-safe only on a freshly constructed record; once
loaded, it is a non-thread-safe collection again.
Models that need a thread-safe collection currently work around this by
re-wrapping the field in onLoad(). That is easy to forget and is
duplicated across every model that needs it.
Additional consideration
The save path iterates a record's collection fields directly (to
serialize links and enforce constraints) without synchronizing on the
collection. As a result, Collections.synchronizedList is not
sufficient on its own: it guards individual operations but not
iteration, so a concurrent structural modification during a save can
still raise ConcurrentModificationException. A safe default therefore
needs to be iteration-safe under concurrent modification (such as
CopyOnWriteArrayList), or the save path needs to snapshot or
synchronize the collection while iterating it.
Proposal
Provide a field-level annotation (for example @ThreadSafe or
@Concurrent) that instructs Runway to hydrate the annotated collection
field into a thread-safe, iteration-safe collection on load, so a model
no longer needs bespoke onLoad() handling to keep a collection safe
for concurrent access.
Acceptance
- A collection field marked with the annotation is backed by a
thread-safe, iteration-safe collection after a record is loaded, with
no manual onLoad() wrapping.
- Concurrent structural modification during a save does not raise
ConcurrentModificationException.
Problem
When Runway loads a record, it replaces each collection field with a
plain
ArrayList(orLinkedHashSet), discarding any thread-safecollection the field was initialized with. A field declared as, for
example,
Collections.synchronizedList(...)or aCopyOnWriteArrayListis therefore thread-safe only on a freshly constructed record; once
loaded, it is a non-thread-safe collection again.
Models that need a thread-safe collection currently work around this by
re-wrapping the field in
onLoad(). That is easy to forget and isduplicated across every model that needs it.
Additional consideration
The save path iterates a record's collection fields directly (to
serialize links and enforce constraints) without synchronizing on the
collection. As a result,
Collections.synchronizedListis notsufficient on its own: it guards individual operations but not
iteration, so a concurrent structural modification during a save can
still raise
ConcurrentModificationException. A safe default thereforeneeds to be iteration-safe under concurrent modification (such as
CopyOnWriteArrayList), or the save path needs to snapshot orsynchronize the collection while iterating it.
Proposal
Provide a field-level annotation (for example
@ThreadSafeor@Concurrent) that instructs Runway to hydrate the annotated collectionfield into a thread-safe, iteration-safe collection on load, so a model
no longer needs bespoke
onLoad()handling to keep a collection safefor concurrent access.
Acceptance
thread-safe, iteration-safe collection after a record is loaded, with
no manual
onLoad()wrapping.ConcurrentModificationException.