@@ -88,10 +88,21 @@ defmodule Plausible.Ingestion.Event do
88
88
[ :plausible , :ingest , :event , :dropped ]
89
89
end
90
90
91
+ @ spec telemetry_pipeline_step_duration ( ) :: [ atom ( ) ]
91
92
def telemetry_pipeline_step_duration ( ) do
92
93
[ :plausible , :ingest , :pipeline , :step ]
93
94
end
94
95
96
+ @ spec telemetry_ua_parse_timeout ( ) :: [ atom ( ) ]
97
+ def telemetry_ua_parse_timeout ( ) do
98
+ [ :plausible , :ingest , :user_agent_parse , :timeout ]
99
+ end
100
+
101
+ @ spec emit_telemetry_ua_parse_timeout ( ) :: :ok
102
+ def emit_telemetry_ua_parse_timeout ( ) do
103
+ :telemetry . execute ( telemetry_ua_parse_timeout ( ) , % { } , % { } )
104
+ end
105
+
95
106
@ spec emit_telemetry_buffered ( t ( ) ) :: :ok
96
107
def emit_telemetry_buffered ( event ) do
97
108
:telemetry . execute ( telemetry_event_buffered ( ) , % { } , % {
@@ -238,13 +249,13 @@ defmodule Plausible.Ingestion.Event do
238
249
239
250
defp put_user_agent ( % __MODULE__ { } = event , _context ) do
240
251
case parse_user_agent ( event . request ) do
241
- % UAInspector.Result { client: % UAInspector.Result.Client { name: "Headless Chrome" } } ->
252
+ { :ok , % UAInspector.Result { client: % UAInspector.Result.Client { name: "Headless Chrome" } } } ->
242
253
drop ( event , :bot )
243
254
244
- % UAInspector.Result.Bot { } ->
255
+ { :ok , % UAInspector.Result.Bot { } } ->
245
256
drop ( event , :bot )
246
257
247
- % UAInspector.Result { } = user_agent ->
258
+ { :ok , % UAInspector.Result { } = user_agent } ->
248
259
update_session_attrs ( event , % {
249
260
operating_system: os_name ( user_agent ) ,
250
261
operating_system_version: os_version ( user_agent ) ,
@@ -430,14 +441,31 @@ defmodule Plausible.Ingestion.Event do
430
441
|> Enum . find ( fn param_name -> Map . has_key? ( query_params , param_name ) end )
431
442
end
432
443
444
+ @ parse_user_agent_timeout 200
433
445
defp parse_user_agent ( % Request { user_agent: user_agent } ) when is_binary ( user_agent ) do
434
- Plausible.Cache.Adapter . get ( :user_agents , user_agent , fn ->
435
- UAInspector . parse ( user_agent )
446
+ Plausible.Cache.Adapter . fetch ( :user_agents , user_agent , fn ->
447
+ parse_user_agent_safe ( user_agent )
436
448
end )
437
449
end
438
450
439
451
defp parse_user_agent ( request ) , do: request
440
452
453
+ defp parse_user_agent_safe ( user_agent ) do
454
+ task =
455
+ Task.Supervisor . async_nolink ( Plausible.UserAgentParseTaskSupervisor , fn ->
456
+ UAInspector . parse ( user_agent )
457
+ end )
458
+
459
+ case Task . yield ( task , @ parse_user_agent_timeout ) || Task . shutdown ( task ) do
460
+ { :ok , result } ->
461
+ { :ok , result }
462
+
463
+ nil ->
464
+ emit_telemetry_ua_parse_timeout ( )
465
+ { :error , :timeout }
466
+ end
467
+ end
468
+
441
469
defp browser_name ( ua ) do
442
470
case ua . client do
443
471
:unknown -> ""
0 commit comments