[
https://issues.apache.org/jira/browse/ARTEMIS-4197?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Jelmer Marinus updated ARTEMIS-4197:
------------------------------------
Description:
The AbstractJournalStorageManager contains the following code.
{code:java}
@Override
public void storeAddressSetting(PersistedAddressSetting addressSetting) throws
Exception {
deleteAddressSetting(addressSetting.getAddressMatch());
try (ArtemisCloseable lock = closeableReadLock()) {
long id = idGenerator.generateID();
addressSetting.setStoreId(id);
bindingsJournal.appendAddRecord(id,
JournalRecordIds.ADDRESS_SETTING_RECORD, addressSetting, true);
mapPersistedAddressSettings.put(addressSetting.getAddressMatch(),
addressSetting);
}
}{code}
This code is used to update the AddressSettings through, i.e., the Artemis
management API.
is also contains the following code
{code:java}
@Override
public List<PersistedAddressSetting> recoverAddressSettings() throws Exception {
try (ArtemisCloseable lock = closeableReadLock()) {
return new ArrayList<>(mapPersistedAddressSettings.values());
}
} {code}
This code is called during, i.e., a config. reload when i.e. the broker.xml
gets changed.
When a first thread and executes the first code fragement and a second thread
executes the second fragment there is a possibility of the following:
# The first thread executes the deleteAddressSettings for address MY_ADDRESS;
# The second thread runs the whole recoverAddressSettings method
# The first thread runs the remainder of the storeAddressSetting-method for
MY_ADDRESS.
According to the second thread there where no addressSettings for the address
MY_ADDRESS. Because it ran in between the delete and put of the
storeAddressSetting-method.
I think this can be fixed using read-/write-locks from the storageManagerLock.
was:
The `AbstractJournalStorageManager` contains the following code.
{code:java}
@Override
public void storeAddressSetting(PersistedAddressSetting addressSetting) throws
Exception {
deleteAddressSetting(addressSetting.getAddressMatch());
try (ArtemisCloseable lock = closeableReadLock()) {
long id = idGenerator.generateID();
addressSetting.setStoreId(id);
bindingsJournal.appendAddRecord(id,
JournalRecordIds.ADDRESS_SETTING_RECORD, addressSetting, true);
mapPersistedAddressSettings.put(addressSetting.getAddressMatch(),
addressSetting);
}
}{code}
This code is used to update the AddressSettings through, i.e., the Artemis
management API.
is also contains the following code
{code:java}
@Override
public List<PersistedAddressSetting> recoverAddressSettings() throws Exception {
try (ArtemisCloseable lock = closeableReadLock()) {
return new ArrayList<>(mapPersistedAddressSettings.values());
}
} {code}
This code is called during, i.e., a config. reload when i.e. the broker.xml
gets changed.
When a first thread and executes the first code fragement and a second thread
executes the second fragment there is a possibility of the following:
# The first thread executes the deleteAddressSettings for address MY_ADDRESS;
# The second thread runs the whole recoverAddressSettings method
# The first thread runs the remainder of the storeAddressSetting-method for
MY_ADDRESS.
According to the second thread there where no addressSettings for the address
MY_ADDRESS. Because it ran in between the delete and put of the
storeAddressSetting-method.
I think this can be fixed using read-/write-locks from the storageManagerLock.
> AbstractJournalStorageManager address-settings not thread-safe
> --------------------------------------------------------------
>
> Key: ARTEMIS-4197
> URL: https://issues.apache.org/jira/browse/ARTEMIS-4197
> Project: ActiveMQ Artemis
> Issue Type: Bug
> Reporter: Jelmer Marinus
> Priority: Major
>
> The AbstractJournalStorageManager contains the following code.
> {code:java}
> @Override
> public void storeAddressSetting(PersistedAddressSetting addressSetting)
> throws Exception {
> deleteAddressSetting(addressSetting.getAddressMatch());
> try (ArtemisCloseable lock = closeableReadLock()) {
> long id = idGenerator.generateID();
> addressSetting.setStoreId(id);
> bindingsJournal.appendAddRecord(id,
> JournalRecordIds.ADDRESS_SETTING_RECORD, addressSetting, true);
> mapPersistedAddressSettings.put(addressSetting.getAddressMatch(),
> addressSetting);
> }
> }{code}
> This code is used to update the AddressSettings through, i.e., the Artemis
> management API.
> is also contains the following code
> {code:java}
> @Override
> public List<PersistedAddressSetting> recoverAddressSettings() throws
> Exception {
> try (ArtemisCloseable lock = closeableReadLock()) {
> return new ArrayList<>(mapPersistedAddressSettings.values());
> }
> } {code}
> This code is called during, i.e., a config. reload when i.e. the broker.xml
> gets changed.
> When a first thread and executes the first code fragement and a second thread
> executes the second fragment there is a possibility of the following:
> # The first thread executes the deleteAddressSettings for address MY_ADDRESS;
> # The second thread runs the whole recoverAddressSettings method
> # The first thread runs the remainder of the storeAddressSetting-method for
> MY_ADDRESS.
> According to the second thread there where no addressSettings for the address
> MY_ADDRESS. Because it ran in between the delete and put of the
> storeAddressSetting-method.
> I think this can be fixed using read-/write-locks from the storageManagerLock.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)