18
18
19
19
-behaviour (gen_server2 ).
20
20
21
- -export ([start_link /4 , successfully_recovered_state /1 ,
21
+ -export ([start_link /4 , start_global_store_link / 4 , successfully_recovered_state /1 ,
22
22
client_init /4 , client_terminate /1 , client_delete_and_terminate /1 ,
23
23
client_ref /1 , close_all_indicated /1 ,
24
24
write /3 , write_flow /3 , read /2 , contains /2 , remove /2 ]).
63
63
% % the module for index ops,
64
64
% % rabbit_msg_store_ets_index by default
65
65
index_module ,
66
- % % %% where are messages?
66
+ % % where are messages?
67
67
index_state ,
68
68
% % current file name as number
69
69
current_file ,
91
91
flying_ets ,
92
92
% % set of dying clients
93
93
dying_clients ,
94
- % % index of file positions for client death messages
95
- dying_client_index ,
96
94
% % map of references of all registered clients
97
95
% % to callbacks
98
96
clients ,
474
472
% % public API
475
473
% %----------------------------------------------------------------------------
476
474
477
- start_link (Server , Dir , ClientRefs , StartupFunState ) ->
478
- gen_server2 :start_link ({local , Server }, ? MODULE ,
479
- [Server , Dir , ClientRefs , StartupFunState ],
475
+ start_link (Name , Dir , ClientRefs , StartupFunState ) when is_atom (Name ) ->
476
+ gen_server2 :start_link (? MODULE ,
477
+ [Name , Dir , ClientRefs , StartupFunState ],
478
+ [{timeout , infinity }]).
479
+
480
+ start_global_store_link (Name , Dir , ClientRefs , StartupFunState ) when is_atom (Name ) ->
481
+ gen_server2 :start_link ({local , Name }, ? MODULE ,
482
+ [Name , Dir , ClientRefs , StartupFunState ],
480
483
[{timeout , infinity }]).
481
484
482
485
successfully_recovered_state (Server ) ->
483
486
gen_server2 :call (Server , successfully_recovered_state , infinity ).
484
487
485
- client_init (Server , Ref , MsgOnDiskFun , CloseFDsFun ) ->
488
+ client_init (Server , Ref , MsgOnDiskFun , CloseFDsFun ) when is_pid ( Server ); is_atom ( Server ) ->
486
489
{IState , IModule , Dir , GCPid ,
487
490
FileHandlesEts , FileSummaryEts , CurFileCacheEts , FlyingEts } =
488
491
gen_server2 :call (
@@ -522,7 +525,7 @@ write_flow(MsgId, Msg,
522
525
% % rabbit_amqqueue_process process via the
523
526
% % rabbit_variable_queue. We are accessing the
524
527
% % rabbit_amqqueue_process process dictionary.
525
- credit_flow :send (whereis ( Server ) , CreditDiscBound ),
528
+ credit_flow :send (Server , CreditDiscBound ),
526
529
client_write (MsgId , Msg , flow , CState ).
527
530
528
531
write (MsgId , Msg , CState ) -> client_write (MsgId , Msg , noflow , CState ).
@@ -548,7 +551,7 @@ remove(MsgIds, CState = #client_msstate { client_ref = CRef }) ->
548
551
[client_update_flying (- 1 , MsgId , CState ) || MsgId <- MsgIds ],
549
552
server_cast (CState , {remove , CRef , MsgIds }).
550
553
551
- set_maximum_since_use (Server , Age ) ->
554
+ set_maximum_since_use (Server , Age ) when is_pid ( Server ); is_atom ( Server ) ->
552
555
gen_server2 :cast (Server , {set_maximum_since_use , Age }).
553
556
554
557
% %----------------------------------------------------------------------------
@@ -699,27 +702,25 @@ client_update_flying(Diff, MsgId, #client_msstate { flying_ets = FlyingEts,
699
702
end .
700
703
701
704
clear_client (CRef , State = # msstate { cref_to_msg_ids = CTM ,
702
- dying_clients = DyingClients ,
703
- dying_client_index = DyingIndex }) ->
704
- ets :delete (DyingIndex , CRef ),
705
+ dying_clients = DyingClients }) ->
705
706
State # msstate { cref_to_msg_ids = dict :erase (CRef , CTM ),
706
- dying_clients = sets : del_element (CRef , DyingClients ) }.
707
+ dying_clients = maps : remove (CRef , DyingClients ) }.
707
708
708
709
709
710
% %----------------------------------------------------------------------------
710
711
% % gen_server callbacks
711
712
% %----------------------------------------------------------------------------
712
713
713
- init ([Server , BaseDir , ClientRefs , StartupFunState ]) ->
714
+ init ([Name , BaseDir , ClientRefs , StartupFunState ]) ->
714
715
process_flag (trap_exit , true ),
715
716
716
717
ok = file_handle_cache :register_callback (? MODULE , set_maximum_since_use ,
717
718
[self ()]),
718
719
719
- Dir = filename :join (BaseDir , atom_to_list (Server )),
720
+ Dir = filename :join (BaseDir , atom_to_list (Name )),
720
721
721
- {ok , IndexModule } = application :get_env (msg_store_index_module ),
722
- rabbit_log :info (" ~w : using ~p to provide index~n " , [Server , IndexModule ]),
722
+ {ok , IndexModule } = application :get_env (rabbit , msg_store_index_module ),
723
+ rabbit_log :info (" ~tp : using ~p to provide index~n " , [Dir , IndexModule ]),
723
724
724
725
AttemptFileSummaryRecovery =
725
726
case ClientRefs of
@@ -738,7 +739,7 @@ init([Server, BaseDir, ClientRefs, StartupFunState]) ->
738
739
739
740
{CleanShutdown , IndexState , ClientRefs1 } =
740
741
recover_index_and_client_refs (IndexModule , FileSummaryRecovered ,
741
- ClientRefs , Dir , Server ),
742
+ ClientRefs , Dir ),
742
743
Clients = dict :from_list (
743
744
[{CRef , {undefined , undefined , undefined }} ||
744
745
CRef <- ClientRefs1 ]),
@@ -755,10 +756,8 @@ init([Server, BaseDir, ClientRefs, StartupFunState]) ->
755
756
[ordered_set , public ]),
756
757
CurFileCacheEts = ets :new (rabbit_msg_store_cur_file , [set , public ]),
757
758
FlyingEts = ets :new (rabbit_msg_store_flying , [set , public ]),
758
- DyingIndex = ets :new (rabbit_msg_store_dying_client_index ,
759
- [set , public , {keypos , # dying_client .client_ref }]),
760
759
761
- {ok , FileSizeLimit } = application :get_env (msg_store_file_size_limit ),
760
+ {ok , FileSizeLimit } = application :get_env (rabbit , msg_store_file_size_limit ),
762
761
763
762
{ok , GCPid } = rabbit_msg_store_gc :start_link (
764
763
# gc_state { dir = Dir ,
@@ -787,8 +786,7 @@ init([Server, BaseDir, ClientRefs, StartupFunState]) ->
787
786
file_summary_ets = FileSummaryEts ,
788
787
cur_file_cache_ets = CurFileCacheEts ,
789
788
flying_ets = FlyingEts ,
790
- dying_clients = sets :new (),
791
- dying_client_index = DyingIndex ,
789
+ dying_clients = #{},
792
790
clients = Clients ,
793
791
successfully_recovered = CleanShutdown ,
794
792
file_size_limit = FileSizeLimit ,
@@ -866,14 +864,14 @@ handle_call({contains, MsgId}, From, State) ->
866
864
867
865
handle_cast ({client_dying , CRef },
868
866
State = # msstate { dying_clients = DyingClients ,
869
- dying_client_index = DyingIndex ,
870
867
current_file_handle = CurHdl ,
871
868
current_file = CurFile }) ->
872
- DyingClients1 = sets :add_element (CRef , DyingClients ),
873
869
{ok , CurOffset } = file_handle_cache :current_virtual_offset (CurHdl ),
874
- true = ets :insert_new (DyingIndex , # dying_client {client_ref = CRef ,
875
- file = CurFile ,
876
- offset = CurOffset }),
870
+ DyingClients1 = maps :put (CRef ,
871
+ # dying_client {client_ref = CRef ,
872
+ file = CurFile ,
873
+ offset = CurOffset },
874
+ DyingClients ),
877
875
noreply (State # msstate { dying_clients = DyingClients1 });
878
876
879
877
handle_cast ({client_delete , CRef },
@@ -995,12 +993,25 @@ terminate(_Reason, State = #msstate { index_state = IndexState,
995
993
State2
996
994
end ,
997
995
State3 = close_all_handles (State1 ),
998
- ok = store_file_summary (FileSummaryEts , Dir ),
996
+ case store_file_summary (FileSummaryEts , Dir ) of
997
+ ok -> ok ;
998
+ {error , FSErr } ->
999
+ rabbit_log :error (" Unable to store file summary"
1000
+ " for vhost message store for directory ~p~n "
1001
+ " Error: ~p~n " ,
1002
+ [Dir , FSErr ])
1003
+ end ,
999
1004
[true = ets :delete (T ) || T <- [FileSummaryEts , FileHandlesEts ,
1000
1005
CurFileCacheEts , FlyingEts ]],
1001
1006
IndexModule :terminate (IndexState ),
1002
- ok = store_recovery_terms ([{client_refs , dict :fetch_keys (Clients )},
1003
- {index_module , IndexModule }], Dir ),
1007
+ case store_recovery_terms ([{client_refs , dict :fetch_keys (Clients )},
1008
+ {index_module , IndexModule }], Dir ) of
1009
+ ok -> ok ;
1010
+ {error , RTErr } ->
1011
+ rabbit_log :error (" Unable to save message store recovery terms"
1012
+ " for directory ~p~n Error: ~p~n " ,
1013
+ [Dir , RTErr ])
1014
+ end ,
1004
1015
State3 # msstate { index_state = undefined ,
1005
1016
current_file_handle = undefined }.
1006
1017
@@ -1357,17 +1368,15 @@ blind_confirm(CRef, MsgIds, ActionTaken, State) ->
1357
1368
% % msg and thus should be ignored. Note that this (correctly) returns
1358
1369
% % false when testing to remove the death msg itself.
1359
1370
should_mask_action (CRef , MsgId ,
1360
- State = # msstate { dying_clients = DyingClients ,
1361
- dying_client_index = DyingIndex }) ->
1362
- case {sets :is_element (CRef , DyingClients ), index_lookup (MsgId , State )} of
1363
- {false , Location } ->
1371
+ State = # msstate {dying_clients = DyingClients }) ->
1372
+ case {maps :find (CRef , DyingClients ), index_lookup (MsgId , State )} of
1373
+ {error , Location } ->
1364
1374
{false , Location };
1365
- {true , not_found } ->
1375
+ {{ ok , _ } , not_found } ->
1366
1376
{true , not_found };
1367
- {true , # msg_location { file = File , offset = Offset ,
1368
- ref_count = RefCount } = Location } ->
1369
- [# dying_client { file = DeathFile , offset = DeathOffset }] =
1370
- ets :lookup (DyingIndex , CRef ),
1377
+ {{ok , Client }, # msg_location { file = File , offset = Offset ,
1378
+ ref_count = RefCount } = Location } ->
1379
+ # dying_client {file = DeathFile , offset = DeathOffset } = Client ,
1371
1380
{case {{DeathFile , DeathOffset } < {File , Offset }, RefCount } of
1372
1381
{true , _ } -> true ;
1373
1382
{false , 0 } -> false_if_increment ;
@@ -1538,16 +1547,16 @@ index_delete_by_file(File, #msstate { index_module = Index,
1538
1547
% % shutdown and recovery
1539
1548
% %----------------------------------------------------------------------------
1540
1549
1541
- recover_index_and_client_refs (IndexModule , _Recover , undefined , Dir , _Server ) ->
1550
+ recover_index_and_client_refs (IndexModule , _Recover , undefined , Dir ) ->
1542
1551
{false , IndexModule :new (Dir ), []};
1543
- recover_index_and_client_refs (IndexModule , false , _ClientRefs , Dir , Server ) ->
1544
- rabbit_log :warning (" ~w : rebuilding indices from scratch~n " , [Server ]),
1552
+ recover_index_and_client_refs (IndexModule , false , _ClientRefs , Dir ) ->
1553
+ rabbit_log :warning (" ~tp : rebuilding indices from scratch~n " , [Dir ]),
1545
1554
{false , IndexModule :new (Dir ), []};
1546
- recover_index_and_client_refs (IndexModule , true , ClientRefs , Dir , Server ) ->
1555
+ recover_index_and_client_refs (IndexModule , true , ClientRefs , Dir ) ->
1547
1556
Fresh = fun (ErrorMsg , ErrorArgs ) ->
1548
- rabbit_log :warning (" ~w : " ++ ErrorMsg ++ " ~n "
1557
+ rabbit_log :warning (" ~tp : " ++ ErrorMsg ++ " ~n "
1549
1558
" rebuilding indices from scratch~n " ,
1550
- [Server | ErrorArgs ]),
1559
+ [Dir | ErrorArgs ]),
1551
1560
{false , IndexModule :new (Dir ), []}
1552
1561
end ,
1553
1562
case read_recovery_terms (Dir ) of
@@ -1582,7 +1591,7 @@ read_recovery_terms(Dir) ->
1582
1591
end .
1583
1592
1584
1593
store_file_summary (Tid , Dir ) ->
1585
- ok = ets :tab2file (Tid , filename :join (Dir , ? FILE_SUMMARY_FILENAME ),
1594
+ ets :tab2file (Tid , filename :join (Dir , ? FILE_SUMMARY_FILENAME ),
1586
1595
[{extended_info , [object_count ]}]).
1587
1596
1588
1597
recover_file_summary (false , _Dir ) ->
0 commit comments