Skip to content

Commit cb85739

Browse files
committed
RDBC-768 RavenDB_13034Test::exploringConcurrencyBehavior
1 parent 3900bff commit cb85739

File tree

4 files changed

+127
-72
lines changed

4 files changed

+127
-72
lines changed

ravendb/documents/session/document_session.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,14 @@ def transaction_mode(self) -> TransactionMode:
588588
def transaction_mode(self, value: TransactionMode):
589589
self._session.transaction_mode = value
590590

591+
@property
592+
def use_optimistic_concurrency(self) -> bool:
593+
return self._session._use_optimistic_concurrency
594+
595+
@use_optimistic_concurrency.setter
596+
def use_optimistic_concurrency(self, value: bool):
597+
self._session._use_optimistic_concurrency = value
598+
591599
def is_loaded(self, key: str) -> bool:
592600
return self._session.is_loaded_or_deleted(key)
593601

ravendb/documents/session/document_session_operations/in_memory_document_session_operations.py

Lines changed: 69 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -423,32 +423,30 @@ def __exit__(self, exc_type, exc_val, exc_tb):
423423
self.close()
424424

425425
def __init__(self, store: "DocumentStore", key: uuid.UUID, options: SessionOptions):
426-
self.__id = key
427-
self.__database_name = options.database if options.database else store.database if store.database else None
428-
if not self.__database_name:
426+
self._id = key
427+
self._database_name = options.database if options.database else store.database if store.database else None
428+
if not self._database_name:
429429
InMemoryDocumentSessionOperations.raise_no_database()
430430

431431
self._request_executor = (
432-
options.request_executor if options.request_executor else store.get_request_executor(self.__database_name)
432+
options.request_executor if options.request_executor else store.get_request_executor(self._database_name)
433433
)
434434
self._operation_executor: Union[None, OperationExecutor] = None
435435

436436
self._pending_lazy_operations: List[LazyOperation] = []
437437
self._on_evaluate_lazy = {}
438438

439-
self.__no_tracking = options.no_tracking
439+
self._no_tracking = options.no_tracking
440440

441-
self.__use_optimistic_concurrency = self._request_executor.conventions.use_optimistic_concurrency
442-
self.__max_number_of_requests_per_session = (
443-
self._request_executor.conventions.max_number_of_requests_per_session
444-
)
445-
self.__generate_entity_id_on_client = GenerateEntityIdOnTheClient(
441+
self._use_optimistic_concurrency = self._request_executor.conventions.use_optimistic_concurrency
442+
self._max_number_of_requests_per_session = self._request_executor.conventions.max_number_of_requests_per_session
443+
self._generate_entity_id_on_client = GenerateEntityIdOnTheClient(
446444
self._request_executor.conventions, self._generate_id
447445
)
448446
self.entity_to_json = EntityToJson(self)
449447
self._document_store: DocumentStore = store
450448
self.session_info = SessionInfo(self, options, self._document_store)
451-
self.__save_changes_options = BatchOptions()
449+
self._save_changes_options = BatchOptions()
452450

453451
self.transaction_mode = options.transaction_mode
454452
self.disable_atomic_document_writes_in_cluster_wide_transaction = (
@@ -472,124 +470,124 @@ def __init__(self, store: "DocumentStore", key: uuid.UUID, options: SessionOptio
472470
# todo: pendingLazyOperations, onEvaluateLazy
473471
self._generate_document_keys_on_store: bool = True
474472
self._save_changes_options: Union[None, BatchOptions] = None
475-
self.__hash: int = self.__instances_counter.__add__(1)
476-
self.__is_disposed: Union[None, bool] = None
473+
self._hash: int = self.__instances_counter.__add__(1)
474+
self._is_disposed: Union[None, bool] = None
477475

478-
self.__number_of_requests: int = 0
479-
self.__max_number_of_requests_per_session: int = (
476+
self._number_of_requests: int = 0
477+
self._max_number_of_requests_per_session: int = (
480478
self._request_executor.conventions.max_number_of_requests_per_session
481479
)
482480

483481
# --- EVENTS ---
484-
self.__before_store: List[Callable[[BeforeStoreEventArgs], None]] = []
485-
self.__after_save_changes: List[Callable[[AfterSaveChangesEventArgs], None]] = []
486-
self.__before_delete: List[Callable[[BeforeDeleteEventArgs], None]] = []
487-
self.__before_query: List[Callable[[BeforeQueryEventArgs], None]] = []
488-
self.__before_conversion_to_document: List[Callable[[BeforeConversionToDocumentEventArgs], None]] = []
489-
self.__after_conversion_to_document: List[Callable[[AfterConversionToDocumentEventArgs], None]] = []
482+
self._before_store: List[Callable[[BeforeStoreEventArgs], None]] = []
483+
self._after_save_changes: List[Callable[[AfterSaveChangesEventArgs], None]] = []
484+
self._before_delete: List[Callable[[BeforeDeleteEventArgs], None]] = []
485+
self._before_query: List[Callable[[BeforeQueryEventArgs], None]] = []
486+
self._before_conversion_to_document: List[Callable[[BeforeConversionToDocumentEventArgs], None]] = []
487+
self._after_conversion_to_document: List[Callable[[AfterConversionToDocumentEventArgs], None]] = []
490488

491-
self.__before_conversion_to_entity: List[Callable[[BeforeConversionToEntityEventArgs], None]] = []
489+
self._before_conversion_to_entity: List[Callable[[BeforeConversionToEntityEventArgs], None]] = []
492490

493-
self.__after_conversion_to_entity: List[Callable[[AfterConversionToEntityEventArgs], None]] = []
491+
self._after_conversion_to_entity: List[Callable[[AfterConversionToEntityEventArgs], None]] = []
494492

495-
self.__session_closing: List[Callable[[SessionClosingEventArgs], None]] = []
493+
self._session_closing: List[Callable[[SessionClosingEventArgs], None]] = []
496494

497495
def add_before_store(self, event: Callable[[BeforeStoreEventArgs], None]):
498-
self.__before_store.append(event)
496+
self._before_store.append(event)
499497

500498
def remove_before_store(self, event: Callable[[BeforeStoreEventArgs], None]):
501-
self.__before_store.remove(event)
499+
self._before_store.remove(event)
502500

503501
def add_session_closing(self, event: Callable[[SessionClosingEventArgs], None]):
504-
self.__session_closing.append(event)
502+
self._session_closing.append(event)
505503

506504
def remove_session_closing(self, event: Callable[[SessionClosingEventArgs], None]):
507-
self.__session_closing.remove(event)
505+
self._session_closing.remove(event)
508506

509507
def add_before_conversion_to_document(self, event: Callable[[BeforeConversionToDocumentEventArgs], None]):
510-
self.__before_conversion_to_document.append(event)
508+
self._before_conversion_to_document.append(event)
511509

512510
def remove_before_conversion_to_document(self, event: Callable[[BeforeConversionToDocumentEventArgs], None]):
513-
self.__before_conversion_to_document.remove(event)
511+
self._before_conversion_to_document.remove(event)
514512

515513
def add_after_conversion_to_document(self, event: Callable[[AfterConversionToDocumentEventArgs], None]):
516-
self.__after_conversion_to_document.append(event)
514+
self._after_conversion_to_document.append(event)
517515

518516
def remove_after_conversion_to_document(self, event: Callable[[AfterConversionToDocumentEventArgs], None]):
519-
self.__after_conversion_to_document.remove(event)
517+
self._after_conversion_to_document.remove(event)
520518

521519
def add_before_conversion_to_entity(self, event: Callable[[BeforeConversionToEntityEventArgs], None]):
522-
self.__before_conversion_to_entity.append(event)
520+
self._before_conversion_to_entity.append(event)
523521

524522
def remove_before_conversion_to_entity(self, event: Callable[[BeforeConversionToEntityEventArgs], None]):
525-
self.__before_conversion_to_entity.remove(event)
523+
self._before_conversion_to_entity.remove(event)
526524

527525
def add_after_conversion_to_entity(self, event: Callable[[AfterConversionToEntityEventArgs], None]):
528-
self.__after_conversion_to_entity.append(event)
526+
self._after_conversion_to_entity.append(event)
529527

530528
def remove_after_conversion_to_entity(self, event: Callable[[AfterConversionToEntityEventArgs], None]):
531-
self.__after_conversion_to_entity.remove(event)
529+
self._after_conversion_to_entity.remove(event)
532530

533531
def add_after_save_changes(self, event: Callable[[AfterSaveChangesEventArgs], None]):
534-
self.__after_save_changes.append(event)
532+
self._after_save_changes.append(event)
535533

536534
def remove_after_save_changes(self, event: Callable[[AfterSaveChangesEventArgs], None]):
537-
self.__after_save_changes.remove(event)
535+
self._after_save_changes.remove(event)
538536

539537
def add_before_delete(self, event: Callable[[BeforeDeleteEventArgs], None]):
540-
self.__before_delete.append(event)
538+
self._before_delete.append(event)
541539

542540
def remove_before_delete_entity(self, event: Callable[[BeforeDeleteEventArgs], None]):
543-
self.__before_delete.remove(event)
541+
self._before_delete.remove(event)
544542

545543
def add_before_query(self, event: Callable[[BeforeQueryEventArgs], None]):
546-
self.__before_query.append(event)
544+
self._before_query.append(event)
547545

548546
def remove_before_query(self, event: Callable[[BeforeQueryEventArgs], None]):
549-
self.__before_query.append(event)
547+
self._before_query.append(event)
550548

551549
def before_store_invoke(self, before_store_event_args: BeforeStoreEventArgs):
552-
for event in self.__before_store:
550+
for event in self._before_store:
553551
event(before_store_event_args)
554552

555553
def session_closing_invoke(self, session_closing_event_args: SessionClosingEventArgs):
556-
for event in self.__session_closing:
554+
for event in self._session_closing:
557555
event(session_closing_event_args)
558556

559557
def before_conversion_to_document_invoke(
560558
self, before_conversion_to_document_event_args: BeforeConversionToDocumentEventArgs
561559
):
562-
for event in self.__before_conversion_to_document:
560+
for event in self._before_conversion_to_document:
563561
event(before_conversion_to_document_event_args)
564562

565563
def after_conversion_to_document_invoke(
566564
self, after_conversion_to_document_event_args: AfterConversionToDocumentEventArgs
567565
):
568-
for event in self.__after_conversion_to_document:
566+
for event in self._after_conversion_to_document:
569567
event(after_conversion_to_document_event_args)
570568

571569
def before_conversion_to_entity_invoke(
572570
self, before_conversion_to_entity_event_args: BeforeConversionToEntityEventArgs
573571
):
574-
for event in self.__before_conversion_to_entity:
572+
for event in self._before_conversion_to_entity:
575573
event(before_conversion_to_entity_event_args)
576574

577575
def after_conversion_to_entity_invoke(
578576
self, after_conversion_to_entity_event_args: AfterConversionToEntityEventArgs
579577
):
580-
for event in self.__after_conversion_to_entity:
578+
for event in self._after_conversion_to_entity:
581579
event(after_conversion_to_entity_event_args)
582580

583581
def after_save_changes_invoke(self, after_save_changes_event_args: AfterSaveChangesEventArgs):
584-
for event in self.__after_save_changes:
582+
for event in self._after_save_changes:
585583
event(after_save_changes_event_args)
586584

587585
def before_delete_invoke(self, before_delete_event_args: BeforeDeleteEventArgs):
588-
for event in self.__before_delete:
586+
for event in self._before_delete:
589587
event(before_delete_event_args)
590588

591589
def before_query_invoke(self, before_query_event_args: BeforeQueryEventArgs):
592-
for event in self.__before_query:
590+
for event in self._before_query:
593591
event(before_query_event_args)
594592

595593
@property
@@ -622,11 +620,11 @@ def _store_identifier(self):
622620

623621
@property
624622
def database_name(self):
625-
return self.__database_name
623+
return self._database_name
626624

627625
@property
628626
def generate_entity_id_on_the_client(self) -> GenerateEntityIdOnTheClient:
629-
return self.__generate_entity_id_on_client
627+
return self._generate_entity_id_on_client
630628

631629
@property
632630
def counters_by_doc_id(self):
@@ -640,15 +638,15 @@ def time_series_by_doc_id(self) -> Dict[str, Dict[str, List[TimeSeriesRangeResul
640638

641639
@property
642640
def number_of_requests(self) -> int:
643-
return self.__number_of_requests
641+
return self._number_of_requests
644642

645643
@property
646644
def no_tracking(self) -> bool:
647-
return self.__no_tracking
645+
return self._no_tracking
648646

649647
@no_tracking.setter
650648
def no_tracking(self, value: bool):
651-
self.__no_tracking = value
649+
self._no_tracking = value
652650

653651
# def counters_for(self, entity_or_document_id):
654652
# """
@@ -673,7 +671,7 @@ def _get_document_info(self, entity: object) -> DocumentInfo:
673671
if document_info:
674672
return document_info
675673

676-
found, value = self.__generate_entity_id_on_client.try_get_id_from_instance(entity)
674+
found, value = self._generate_entity_id_on_client.try_get_id_from_instance(entity)
677675
if not found:
678676
raise ValueError(f"Could not find the document id for {entity}")
679677
self._assert_no_non_unique_instance(entity, value)
@@ -695,10 +693,10 @@ def is_deleted(self, key: str) -> bool:
695693
return key in self._known_missing_ids
696694

697695
def increment_requests_count(self) -> None:
698-
self.__number_of_requests += 1
699-
if self.__number_of_requests > self.__max_number_of_requests_per_session:
696+
self._number_of_requests += 1
697+
if self._number_of_requests > self._max_number_of_requests_per_session:
700698
raise ValueError(
701-
f"The maximum number of requests {self.__max_number_of_requests_per_session} allowed for this session"
699+
f"The maximum number of requests {self._max_number_of_requests_per_session} allowed for this session"
702700
"has been reached. "
703701
"Raven limits the number of remote calls that a session is allowed to make as an early warning system. "
704702
"Sessions are expected to be short lived, and Raven provides facilities like load(String[] keys) "
@@ -819,7 +817,7 @@ def delete(self, key_or_entity: Union[str, object], expected_change_vector: Opti
819817
change_vector = document_info.change_vector
820818

821819
self._known_missing_ids.add(key)
822-
change_vector = change_vector if self.__use_optimistic_concurrency else None
820+
change_vector = change_vector if self._use_optimistic_concurrency else None
823821
if self._counters_by_doc_id:
824822
self._counters_by_doc_id.pop(key, None)
825823
self.defer(
@@ -849,7 +847,7 @@ def delete(self, key_or_entity: Union[str, object], expected_change_vector: Opti
849847

850848
def store(self, entity: object, key: Optional[str] = None, change_vector: Optional[str] = None) -> None:
851849
if all([entity, not key, not change_vector]):
852-
has_id = self.__generate_entity_id_on_client.try_get_id_from_instance(entity)[0]
850+
has_id = self._generate_entity_id_on_client.try_get_id_from_instance(entity)[0]
853851
checkmode = ConcurrencyCheckMode.FORCED if not has_id else ConcurrencyCheckMode.AUTO
854852
elif all([entity, key, not change_vector]):
855853
checkmode = ConcurrencyCheckMode.AUTO
@@ -875,11 +873,11 @@ def __store_internal(
875873

876874
if key is None:
877875
if self._generate_document_keys_on_store:
878-
key = self.__generate_entity_id_on_client.generate_document_key_for_storage(entity)
876+
key = self._generate_entity_id_on_client.generate_document_key_for_storage(entity)
879877
else:
880878
self._remember_entity_for_document_id_generation(entity)
881879
else:
882-
self.__generate_entity_id_on_client.try_set_identity(entity, key)
880+
self._generate_entity_id_on_client.try_set_identity(entity, key)
883881

884882
if IdTypeAndName.create(key, CommandType.CLIENT_ANY_COMMAND, None) in self._deferred_commands_map.keys():
885883
raise InvalidOperationException(
@@ -959,7 +957,7 @@ def validate_cluster_transaction(self, result: SaveChangesData) -> None:
959957
if self.transaction_mode != TransactionMode.CLUSTER_WIDE:
960958
return
961959

962-
if self.__use_optimistic_concurrency:
960+
if self._use_optimistic_concurrency:
963961
raise RuntimeError(
964962
f"useOptimisticConcurrency is not supported with TransactionMode set to {TransactionMode.CLUSTER_WIDE}"
965963
)
@@ -1042,7 +1040,7 @@ def __prepare_for_entities_deletion(
10421040

10431041
result.on_success.remove_document_by_id(document_info.key)
10441042

1045-
change_vector = change_vector if self.__use_optimistic_concurrency else None
1043+
change_vector = change_vector if self._use_optimistic_concurrency else None
10461044
self.before_delete_invoke(BeforeDeleteEventArgs(self, document_info.key, document_info.entity))
10471045
result.session_commands.append(
10481046
DeleteCommandData(document_info.key, change_vector, document_info.change_vector)
@@ -1078,7 +1076,7 @@ def __prepare_for_entities_puts(self, result: SaveChangesData) -> None:
10781076
if command:
10791077
self.__throw_invalid_modified_document_with_deferred_command(command)
10801078

1081-
if self.__before_store and entity.execute_on_before_store:
1079+
if self._before_store and entity.execute_on_before_store:
10821080
before_store_event_args = BeforeStoreEventArgs(self, entity.value.key, entity.key)
10831081
self.before_store_invoke(before_store_event_args)
10841082

@@ -1097,7 +1095,7 @@ def __prepare_for_entities_puts(self, result: SaveChangesData) -> None:
10971095

10981096
change_vector = (
10991097
(entity.value.change_vector if entity.value.change_vector else "")
1100-
if self.__use_optimistic_concurrency
1098+
if self._use_optimistic_concurrency
11011099
else (
11021100
entity.value.change_vector
11031101
if entity.value.concurrency_check_mode == ConcurrencyCheckMode.FORCED
@@ -1202,11 +1200,11 @@ def __add_command(self, command: CommandData, key: str, command_type: CommandTyp
12021200
)
12031201

12041202
def __close(self, is_disposing: bool) -> None:
1205-
if self.__is_disposed:
1203+
if self._is_disposed:
12061204
return
12071205

12081206
self.session_closing_invoke(SessionClosingEventArgs(self))
1209-
self.__is_disposed = True
1207+
self._is_disposed = True
12101208

12111209
def close(self) -> None:
12121210
self.__close(True)
@@ -1693,7 +1691,7 @@ def __update_existing_range(local_range: TimeSeriesRangeResult, new_range: TimeS
16931691
local_range.entries = new_values
16941692

16951693
def hash_code(self) -> int:
1696-
return self.__hash
1694+
return self._hash
16971695

16981696
def __deserialize_from_transformer(
16991697
self, object_type: Type[_T], key: Union[None, str], document: dict, track_entity: bool

ravendb/http/request_executor.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1061,7 +1061,11 @@ def __handle_unsuccessful_response(
10611061
)
10621062

10631063
elif response.status_code == HTTPStatus.CONFLICT:
1064-
raise NotImplementedError("Handle conflict") # todo: handle conflict (exception dispatcher involved)
1064+
data = json.loads(response.text)
1065+
message = data.get("Message", None)
1066+
err_type = data.get("Type", None)
1067+
1068+
raise RuntimeError(f"{err_type}: {message}") # todo: handle conflict (exception dispatcher involved)
10651069

10661070
elif response.status_code == 425: # too early
10671071
if not should_retry:

0 commit comments

Comments
 (0)