You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@activemq.apache.org by "Jelmer Marinus (Jira)" <ji...@apache.org> on 2023/03/06 15:08:00 UTC

[jira] [Updated] (ARTEMIS-4197) AbstractJournalStorageManager address-settings not thread-safe

     [ 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)