2121
2222-define (BY_SIG , dreyfus_by_sig ).
2323-define (BY_PID , dreyfus_by_pid ).
24+ -define (BY_DB , dreyfus_by_db ).
2425
2526% public api.
2627-export ([start_link /0 , get_index /2 , get_disk_size /2 ]).
@@ -44,8 +45,9 @@ get_disk_size(DbName, Index) ->
4445% gen_server functions.
4546
4647init ([]) ->
47- ets :new (? BY_SIG , [set , private , named_table ]),
48+ ets :new (? BY_SIG , [set , protected , named_table ]),
4849 ets :new (? BY_PID , [set , private , named_table ]),
50+ ets :new (? BY_DB , [bag , protected , named_table ]),
4951 couch_event :link_listener (? MODULE , handle_db_event , nil , [all_dbs ]),
5052 process_flag (trap_exit , true ),
5153 {ok , nil }.
@@ -69,12 +71,12 @@ handle_call({get_disk_size, DbName, #index{sig=Sig}=Index}, From, State) ->
6971 Reply = clouseau_rpc :disk_size (Path ),
7072 {reply , Reply , State };
7173
72- handle_call ({open_ok , DbName , Sig , NewPid }, {OpenerPid , _ }, State ) ->
74+ handle_call ({open_ok , DbName , DDocId , Sig , NewPid }, {OpenerPid , _ }, State ) ->
7375 link (NewPid ),
7476 [{_ , WaitList }] = ets :lookup (? BY_SIG , {DbName , Sig }),
7577 [gen_server :reply (From , {ok , NewPid }) || From <- WaitList ],
7678 ets :delete (? BY_PID , OpenerPid ),
77- add_to_ets (NewPid , DbName , Sig ),
79+ add_to_ets (NewPid , DbName , DDocId , Sig ),
7880 {reply , ok , State };
7981
8082handle_call ({open_error , DbName , Sig , Error }, {OpenerPid , _ }, State ) ->
@@ -121,25 +123,49 @@ handle_db_event(DbName, created, _St) ->
121123handle_db_event (DbName , deleted , _St ) ->
122124 gen_server :cast (? MODULE , {cleanup , DbName }),
123125 {ok , nil };
126+ handle_db_event (<<" shards/" , _ /binary >> = DbName , {ddoc_updated , DDocId }, _St ) ->
127+ DDocResult = couch_util :with_db (DbName , fun (Db ) ->
128+ couch_db :open_doc (Db , DDocId , [ejson_body , ? ADMIN_CTX ])
129+ end ),
130+ couch_log :info (" Received ddoc_updated event for ~s " ,[DDocId ]),
131+ DbShards = [mem3 :name (Sh ) || Sh <- mem3 :local_shards (mem3 :dbname (DbName ))],
132+ lists :foreach (fun (DbShard ) ->
133+ lists :foreach (fun ({_DbShard , {_DDocId , Sig }}) ->
134+ case ets :lookup (? BY_SIG , {DbShard , Sig }) of
135+ [{_ , IndexPid }] ->
136+ gen_server :cast (IndexPid , {ddoc_updated , DDocResult });
137+ [] ->
138+ ok
139+ end
140+ end , ets :match_object (? BY_DB , {DbShard , {DDocId , '$1' }}))
141+ end , DbShards ),
142+ {ok , nil };
124143handle_db_event (_DbName , _Event , _St ) ->
125144 {ok , nil }.
126145
127- new_index (DbName , # index {sig = Sig }= Index ) ->
146+ new_index (DbName , # index {ddoc_id = DDocId , sig = Sig }= Index ) ->
128147 case (catch dreyfus_index :start_link (DbName , Index )) of
129148 {ok , NewPid } ->
130- Msg = {open_ok , DbName , Sig , NewPid },
149+ Msg = {open_ok , DbName , DDocId , Sig , NewPid },
131150 ok = gen_server :call (? MODULE , Msg , infinity ),
132151 unlink (NewPid );
133152 Error ->
134153 Msg = {open_error , DbName , Sig , Error },
135154 ok = gen_server :call (? MODULE , Msg , infinity )
136155 end .
137156
138- add_to_ets (Pid , DbName , Sig ) ->
157+ add_to_ets (Pid , DbName , DDocId , Sig ) ->
139158 true = ets :insert (? BY_PID , {Pid , {DbName , Sig }}),
140- true = ets :insert (? BY_SIG , {{DbName , Sig }, Pid }).
159+ true = ets :insert (? BY_SIG , {{DbName , Sig }, Pid }),
160+ true = ets :insert (? BY_DB , {DbName , {DDocId , Sig }}).
141161
142162delete_from_ets (Pid , DbName , Sig ) ->
163+ case ets :match_object (? BY_DB , {DbName , {'$1' , Sig }}) of
164+ [{DbName , {DDocId , Sig }}] ->
165+ true = ets :delete_object (? BY_DB , {DbName , {DDocId , Sig }});
166+ _Else ->
167+ true
168+ end ,
143169 true = ets :delete (? BY_PID , Pid ),
144170 true = ets :delete (? BY_SIG , {DbName , Sig }).
145171
0 commit comments