@@ -18,6 +18,8 @@ defmodule Extensions.PostgresCdcRls.ReplicationPoller do
18
18
alias Realtime.Adapters.Changes.NewRecord
19
19
alias Realtime.Adapters.Changes.UpdatedRecord
20
20
alias Realtime.Database
21
+ alias Realtime.RateCounter
22
+ alias Realtime.Tenants
21
23
22
24
def start_link ( opts ) , do: GenServer . start_link ( __MODULE__ , opts )
23
25
@@ -26,6 +28,12 @@ defmodule Extensions.PostgresCdcRls.ReplicationPoller do
26
28
tenant_id = args [ "id" ]
27
29
Logger . metadata ( external_id: tenant_id , project: tenant_id )
28
30
31
+ % Realtime.Api.Tenant { } = Tenants.Cache . get_tenant_by_external_id ( tenant_id )
32
+
33
+ rate_counter_args = Tenants . db_events_per_second_rate ( tenant_id , 4000 )
34
+
35
+ RateCounter . new ( rate_counter_args )
36
+
29
37
state = % {
30
38
backoff: Backoff . new ( backoff_min: 100 , backoff_max: 5_000 , backoff_type: :rand_exp ) ,
31
39
db_host: args [ "db_host" ] ,
@@ -41,7 +49,8 @@ defmodule Extensions.PostgresCdcRls.ReplicationPoller do
41
49
retry_ref: nil ,
42
50
retry_count: 0 ,
43
51
slot_name: args [ "slot_name" ] <> slot_name_suffix ( ) ,
44
- tenant_id: tenant_id
52
+ tenant_id: tenant_id ,
53
+ rate_counter_args: rate_counter_args
45
54
}
46
55
47
56
{ :ok , _ } = Registry . register ( __MODULE__ . Registry , tenant_id , % { } )
@@ -74,7 +83,8 @@ defmodule Extensions.PostgresCdcRls.ReplicationPoller do
74
83
max_record_bytes: max_record_bytes ,
75
84
max_changes: max_changes ,
76
85
conn: conn ,
77
- tenant_id: tenant_id
86
+ tenant_id: tenant_id ,
87
+ rate_counter_args: rate_counter_args
78
88
} = state
79
89
) do
80
90
cancel_timer ( poll_ref )
@@ -84,7 +94,7 @@ defmodule Extensions.PostgresCdcRls.ReplicationPoller do
84
94
{ time , list_changes } = :timer . tc ( Replications , :list_changes , args )
85
95
record_list_changes_telemetry ( time , tenant_id )
86
96
87
- case handle_list_changes_result ( list_changes , tenant_id ) do
97
+ case handle_list_changes_result ( list_changes , tenant_id , rate_counter_args ) do
88
98
{ :ok , row_count } ->
89
99
Backoff . reset ( backoff )
90
100
@@ -177,20 +187,29 @@ defmodule Extensions.PostgresCdcRls.ReplicationPoller do
177
187
rows: [ _ | _ ] = rows ,
178
188
num_rows: rows_count
179
189
} } ,
180
- tenant_id
190
+ tenant_id ,
191
+ rate_counter_args
181
192
) do
182
- for row <- rows ,
183
- change <- columns |> Enum . zip ( row ) |> generate_record ( ) |> List . wrap ( ) do
184
- topic = "realtime:postgres:" <> tenant_id
193
+ case RateCounter . get ( rate_counter_args ) do
194
+ { :ok , % { limit: % { triggered: true } } } ->
195
+ :ok
185
196
186
- RealtimeWeb.TenantBroadcaster . pubsub_broadcast ( tenant_id , topic , change , MessageDispatcher , :postgres_changes )
197
+ _ ->
198
+ Realtime.GenCounter . add ( rate_counter_args . id , rows_count )
199
+
200
+ for row <- rows ,
201
+ change <- columns |> Enum . zip ( row ) |> generate_record ( ) |> List . wrap ( ) do
202
+ topic = "realtime:postgres:" <> tenant_id
203
+
204
+ RealtimeWeb.TenantBroadcaster . pubsub_broadcast ( tenant_id , topic , change , MessageDispatcher , :postgres_changes )
205
+ end
187
206
end
188
207
189
208
{ :ok , rows_count }
190
209
end
191
210
192
- defp handle_list_changes_result ( { :ok , _ } , _ ) , do: { :ok , 0 }
193
- defp handle_list_changes_result ( { :error , reason } , _ ) , do: { :error , reason }
211
+ defp handle_list_changes_result ( { :ok , _ } , _ , _ ) , do: { :ok , 0 }
212
+ defp handle_list_changes_result ( { :error , reason } , _ , _ ) , do: { :error , reason }
194
213
195
214
def generate_record ( [
196
215
{ "wal" ,
0 commit comments