Receive race handling from chainqueue, rehabilitate tests
This commit is contained in:
		
							parent
							
								
									4be5325df2
								
							
						
					
					
						commit
						9b98703f24
					
				| @ -1,3 +1,6 @@ | ||||
| - 0.2.0 | ||||
| 	* primitive race condition handling between fs access of sync and queue | ||||
| 	* re-enable throttling based on in-flight transaction count | ||||
| - 0.1.2 | ||||
| 	* add settings object | ||||
| - 0.1.0 | ||||
|  | ||||
| @ -1,10 +1,28 @@ | ||||
| # external imports | ||||
| from chainqueue import Store as QueueStore | ||||
| 
 | ||||
| # local imports | ||||
| from chaind.error import BackendIntegrityError | ||||
| 
 | ||||
| 
 | ||||
| class ChaindAdapter: | ||||
| 
 | ||||
|     race_delay = 0.1 | ||||
| 
 | ||||
|     def __init__(self, chain_spec, state_store, index_store, counter_store, cache_adapter, dispatcher, cache=None, pending_retry_threshold=0, error_retry_threshold=0): | ||||
|         self.cache_adapter = cache_adapter | ||||
|         self.dispatcher = dispatcher | ||||
|         self.store = QueueStore(chain_spec, state_store, index_store, counter_store, cache=cache) | ||||
|         err = None | ||||
|         for i in range(3): | ||||
|             try: | ||||
|                 self.store = QueueStore(chain_spec, state_store, index_store, counter_store, cache=cache) | ||||
|                 err = None | ||||
|                 break | ||||
|             except FileNotFoundError as e: | ||||
|                 logg.debug('queuestore instantiation failed, possible race condition (will try again): {}'.format(tx_hash, e)) | ||||
|                 err = e | ||||
|                 time.sleep(self.race_delay) | ||||
|                 continue | ||||
| 
 | ||||
|         if err != None: | ||||
|             raise BackendIntegrityError(err) | ||||
|  | ||||
| @ -10,12 +10,12 @@ from chainqueue.store.fs import ( | ||||
|         IndexStore, | ||||
|         CounterStore, | ||||
|         ) | ||||
| from chainqueue.error import BackendIntegrityError | ||||
| from shep.store.file import SimpleFileStoreFactory | ||||
| from shep.error import StateInvalid | ||||
| 
 | ||||
| # local imports | ||||
| from .base import ChaindAdapter | ||||
| from chaind.error import BackendIntegrityError | ||||
| 
 | ||||
| logg = logging.getLogger(__name__) | ||||
| 
 | ||||
| @ -38,13 +38,19 @@ class ChaindFsAdapter(ChaindAdapter): | ||||
| 
 | ||||
|     def get(self, tx_hash): | ||||
|         v = None | ||||
|         try: | ||||
|             v = self.store.get(tx_hash) | ||||
|         except StateInvalid as e: | ||||
|             logg.error('I am just a simple syncer and do not know how to handle the state which the tx {} is in: {}'.format(tx_hash, e)) | ||||
|             return None | ||||
|         except FileNotFoundError: | ||||
|             pass | ||||
|         err = None | ||||
|         for i in range(3): | ||||
|             try: | ||||
|                 v = self.store.get(tx_hash) | ||||
|                 err = None | ||||
|             except StateInvalid as e: | ||||
|                 logg.error('I am just a simple syncer and do not know how to handle the state which the tx {} is in: {}'.format(tx_hash, e)) | ||||
|                 return None | ||||
|             except FileNotFoundError as e: | ||||
|                 err = e | ||||
|                 time.sleep(self.race_delay) | ||||
|                 logg.debug('queuestore get {} failed, possible race condition (will try again): {}'.format(tx_hash, e)) | ||||
|                 continue | ||||
|         if v ==None: | ||||
|             raise BackendIntegrityError(tx_hash) | ||||
|         return v[1] | ||||
| @ -52,7 +58,7 @@ class ChaindFsAdapter(ChaindAdapter): | ||||
| 
 | ||||
|     def upcoming(self, limit=0): | ||||
|         real_limit = 0 | ||||
|         in_flight = 0 | ||||
|         in_flight = [] | ||||
|         if limit > 0: | ||||
|             in_flight = self.store.by_state(state=self.store.IN_NETWORK, not_state=self.store.FINAL) | ||||
|             real_limit = limit - len(in_flight) | ||||
|  | ||||
| @ -20,3 +20,7 @@ class ClientInputError(ValueError): | ||||
| 
 | ||||
| class QueueLockError(Exception): | ||||
|     pass | ||||
| 
 | ||||
| 
 | ||||
| class BackendIntegrityError(Exception): | ||||
|     pass | ||||
|  | ||||
| @ -5,14 +5,14 @@ import time | ||||
| # external imports | ||||
| from chainlib.status import Status as TxStatus | ||||
| from chainsyncer.filter import SyncFilter | ||||
| from chainqueue.error import ( | ||||
|         NotLocalTxError, | ||||
|         BackendIntegrityError, | ||||
|         ) | ||||
| from chainqueue.error import NotLocalTxError | ||||
| from chaind.adapters.fs import ChaindFsAdapter | ||||
| 
 | ||||
| # local imports | ||||
| from .error import QueueLockError | ||||
| from .error import ( | ||||
|         QueueLockError, | ||||
|         BackendIntegrityError, | ||||
|         ) | ||||
| 
 | ||||
| logg = logging.getLogger(__name__) | ||||
| 
 | ||||
| @ -20,6 +20,7 @@ logg = logging.getLogger(__name__) | ||||
| class StateFilter(SyncFilter): | ||||
| 
 | ||||
|     delay_limit = 3.0 | ||||
|     race_delay = 0.1 | ||||
| 
 | ||||
|     def __init__(self, chain_spec, adapter_path, tx_adapter, throttler=None): | ||||
|         self.chain_spec = chain_spec | ||||
| @ -41,6 +42,7 @@ class StateFilter(SyncFilter): | ||||
|                     ) | ||||
|             except BackendIntegrityError as e: | ||||
|                 logg.error('adapter instantiation failed: {}, one more try'.format(e)) | ||||
|                 time.sleep(self.race_delay) | ||||
|                 continue | ||||
| 
 | ||||
|             try: | ||||
| @ -50,6 +52,7 @@ class StateFilter(SyncFilter): | ||||
|                 return False | ||||
|             except BackendIntegrityError as e: | ||||
|                 logg.error('adapter instantiation failed: {}, one more try'.format(e)) | ||||
|                 time.sleep(self.race_delay) | ||||
|                 continue | ||||
| 
 | ||||
|             break | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| [metadata] | ||||
| name = chaind | ||||
| version = 0.2.0 | ||||
| version = 0.2.1 | ||||
| description = Base package for chain queue service | ||||
| author = Louis Holbrook | ||||
| author_email = dev@holbrook.no | ||||
|  | ||||
| @ -74,7 +74,7 @@ class TestChaindFs(TestChaindFsBase): | ||||
|         data = os.urandom(128).hex() | ||||
|         hsh = self.adapter.put(data) | ||||
|          | ||||
|         fltr = StateFilter(self.adapter) | ||||
|         fltr = StateFilter(self.chain_spec, self.path, MockCacheAdapter) | ||||
|         tx = MockTx(hsh) | ||||
|         fltr.filter(None, None, tx) | ||||
| 
 | ||||
| @ -85,7 +85,7 @@ class TestChaindFs(TestChaindFsBase): | ||||
|         data = os.urandom(128).hex() | ||||
|         hsh = self.adapter.put(data) | ||||
|          | ||||
|         fltr = StateFilter(self.adapter) | ||||
|         fltr = StateFilter(self.chain_spec, self.path, MockCacheAdapter) | ||||
|         tx = MockTx(hsh, TxStatus.ERROR) | ||||
|         fltr.filter(None, None, tx) | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user