Skip to content

Commit e69667d

Browse files
authored
Merge pull request #9 from gigsmart/fix/streaming-resolution-resolve-then-split
refactor(streaming): resolve-then-split strategy for @defer
2 parents b55f84c + 19fdd17 commit e69667d

24 files changed

Lines changed: 287 additions & 557 deletions

lib/absinthe/blueprint/schema/enum_type_definition.ex

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ defmodule Absinthe.Blueprint.Schema.EnumTypeDefinition do
3636
values: values_by(type_def, :identifier),
3737
values_by_internal_value: values_by(type_def, :value),
3838
values_by_name: values_by(type_def, :name),
39-
applied_directives: Blueprint.Schema.ObjectTypeDefinition.build_applied_directives(type_def.directives),
39+
applied_directives:
40+
Blueprint.Schema.ObjectTypeDefinition.build_applied_directives(type_def.directives),
4041
definition: type_def.module,
4142
description: type_def.description
4243
}
@@ -54,7 +55,8 @@ defmodule Absinthe.Blueprint.Schema.EnumTypeDefinition do
5455
__private__: value_def.__private__,
5556
description: value_def.description,
5657
deprecation: value_def.deprecation,
57-
applied_directives: Blueprint.Schema.ObjectTypeDefinition.build_applied_directives(value_def.directives)
58+
applied_directives:
59+
Blueprint.Schema.ObjectTypeDefinition.build_applied_directives(value_def.directives)
5860
}
5961

6062
{Map.fetch!(value_def, key), value}

lib/absinthe/blueprint/schema/input_object_type_definition.ex

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ defmodule Absinthe.Blueprint.Schema.InputObjectTypeDefinition do
3737
name: type_def.name,
3838
fields: build_fields(type_def, schema),
3939
description: type_def.description,
40-
applied_directives: Blueprint.Schema.ObjectTypeDefinition.build_applied_directives(type_def.directives),
40+
applied_directives:
41+
Blueprint.Schema.ObjectTypeDefinition.build_applied_directives(type_def.directives),
4142
definition: type_def.module
4243
}
4344
end
@@ -50,7 +51,8 @@ defmodule Absinthe.Blueprint.Schema.InputObjectTypeDefinition do
5051
description: field_def.description,
5152
name: field_def.name,
5253
type: Blueprint.TypeReference.to_type(field_def.type, schema),
53-
applied_directives: Blueprint.Schema.ObjectTypeDefinition.build_applied_directives(field_def.directives),
54+
applied_directives:
55+
Blueprint.Schema.ObjectTypeDefinition.build_applied_directives(field_def.directives),
5456
definition: type_def.module,
5557
__reference__: field_def.__reference__,
5658
__private__: field_def.__private__,

lib/absinthe/blueprint/schema/interface_type_definition.ex

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ defmodule Absinthe.Blueprint.Schema.InterfaceTypeDefinition do
4444
fields: Blueprint.Schema.ObjectTypeDefinition.build_fields(type_def, schema),
4545
identifier: type_def.identifier,
4646
resolve_type: type_def.resolve_type,
47-
applied_directives: Blueprint.Schema.ObjectTypeDefinition.build_applied_directives(type_def.directives),
47+
applied_directives:
48+
Blueprint.Schema.ObjectTypeDefinition.build_applied_directives(type_def.directives),
4849
definition: type_def.module,
4950
interfaces: type_def.interfaces
5051
}

lib/absinthe/blueprint/schema/object_type_definition.ex

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -103,34 +103,51 @@ defmodule Absinthe.Blueprint.Schema.ObjectTypeDefinition do
103103
Enum.map(directives, fn directive ->
104104
%{
105105
name: directive.name,
106-
args: Enum.map(directive.arguments, fn arg ->
107-
%{
108-
name: arg.name,
109-
value: serialize_argument_value(arg.input_value)
110-
}
111-
end)
106+
args:
107+
Enum.map(directive.arguments, fn arg ->
108+
%{
109+
name: arg.name,
110+
value: serialize_argument_value(arg.input_value)
111+
}
112+
end)
112113
}
113114
end)
114115
end
115116

116117
def build_applied_directives(_), do: []
117118

118-
defp serialize_argument_value(%Absinthe.Blueprint.Input.String{value: value}), do: inspect(value)
119-
defp serialize_argument_value(%Absinthe.Blueprint.Input.Integer{value: value}), do: to_string(value)
120-
defp serialize_argument_value(%Absinthe.Blueprint.Input.Float{value: value}), do: to_string(value)
121-
defp serialize_argument_value(%Absinthe.Blueprint.Input.Boolean{value: value}), do: to_string(value)
119+
defp serialize_argument_value(%Absinthe.Blueprint.Input.String{value: value}),
120+
do: inspect(value)
121+
122+
defp serialize_argument_value(%Absinthe.Blueprint.Input.Integer{value: value}),
123+
do: to_string(value)
124+
125+
defp serialize_argument_value(%Absinthe.Blueprint.Input.Float{value: value}),
126+
do: to_string(value)
127+
128+
defp serialize_argument_value(%Absinthe.Blueprint.Input.Boolean{value: value}),
129+
do: to_string(value)
130+
122131
defp serialize_argument_value(%Absinthe.Blueprint.Input.Null{}), do: "null"
123132
defp serialize_argument_value(%Absinthe.Blueprint.Input.Enum{value: value}), do: value
133+
124134
defp serialize_argument_value(%Absinthe.Blueprint.Input.List{items: items}) do
125135
"[" <> Enum.map_join(items, ", ", &serialize_argument_value/1) <> "]"
126136
end
137+
127138
defp serialize_argument_value(%Absinthe.Blueprint.Input.Object{fields: fields}) do
128-
"{" <> Enum.map_join(fields, ", ", fn field ->
129-
"#{field.name}: #{serialize_argument_value(field.input_value)}"
130-
end) <> "}"
139+
"{" <>
140+
Enum.map_join(fields, ", ", fn field ->
141+
"#{field.name}: #{serialize_argument_value(field.input_value)}"
142+
end) <> "}"
131143
end
132-
defp serialize_argument_value(%Absinthe.Blueprint.Input.RawValue{content: content}), do: serialize_argument_value(content)
133-
defp serialize_argument_value(%Absinthe.Blueprint.Input.Value{raw: raw}), do: serialize_argument_value(raw)
144+
145+
defp serialize_argument_value(%Absinthe.Blueprint.Input.RawValue{content: content}),
146+
do: serialize_argument_value(content)
147+
148+
defp serialize_argument_value(%Absinthe.Blueprint.Input.Value{raw: raw}),
149+
do: serialize_argument_value(raw)
150+
134151
defp serialize_argument_value(value), do: inspect(value)
135152

136153
defimpl Inspect do

lib/absinthe/blueprint/schema/scalar_type_definition.ex

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,10 @@ defmodule Absinthe.Blueprint.Schema.ScalarTypeDefinition do
3636
identifier: type_def.identifier,
3737
name: type_def.name,
3838
description: type_def.description,
39-
applied_directives: Absinthe.Blueprint.Schema.ObjectTypeDefinition.build_applied_directives(type_def.directives),
39+
applied_directives:
40+
Absinthe.Blueprint.Schema.ObjectTypeDefinition.build_applied_directives(
41+
type_def.directives
42+
),
4043
definition: type_def.module,
4144
serialize: type_def.serialize,
4245
parse: type_def.parse,

lib/absinthe/blueprint/schema/union_type_definition.ex

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ defmodule Absinthe.Blueprint.Schema.UnionTypeDefinition do
3939
identifier: type_def.identifier,
4040
types: type_def.types |> atomize_types(schema),
4141
fields: build_fields(type_def, schema),
42-
applied_directives: Blueprint.Schema.ObjectTypeDefinition.build_applied_directives(type_def.directives),
42+
applied_directives:
43+
Blueprint.Schema.ObjectTypeDefinition.build_applied_directives(type_def.directives),
4344
definition: type_def.module,
4445
resolve_type: type_def.resolve_type
4546
}
@@ -64,7 +65,8 @@ defmodule Absinthe.Blueprint.Schema.UnionTypeDefinition do
6465
name: field_def.name,
6566
type: Blueprint.TypeReference.to_type(field_def.type, schema),
6667
args: build_args(field_def, schema),
67-
applied_directives: Blueprint.Schema.ObjectTypeDefinition.build_applied_directives(field_def.directives),
68+
applied_directives:
69+
Blueprint.Schema.ObjectTypeDefinition.build_applied_directives(field_def.directives),
6870
definition: field_def.module,
6971
__reference__: field_def.__reference__,
7072
__private__: field_def.__private__
@@ -83,7 +85,8 @@ defmodule Absinthe.Blueprint.Schema.UnionTypeDefinition do
8385
type: Blueprint.TypeReference.to_type(arg_def.type, schema),
8486
default_value: arg_def.default_value,
8587
deprecation: arg_def.deprecation,
86-
applied_directives: Blueprint.Schema.ObjectTypeDefinition.build_applied_directives(arg_def.directives),
88+
applied_directives:
89+
Blueprint.Schema.ObjectTypeDefinition.build_applied_directives(arg_def.directives),
8790
__reference__: arg_def.__reference__,
8891
__private__: arg_def.__private__
8992
}

lib/absinthe/incremental/complexity.ex

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,13 @@ defmodule Absinthe.Incremental.Complexity do
368368
end
369369
end
370370

371-
defp analyze_node(%Blueprint.Document.Fragment.Spread{} = node, schema, config, analysis, depth) do
371+
defp analyze_node(
372+
%Blueprint.Document.Fragment.Spread{} = node,
373+
_schema,
374+
config,
375+
analysis,
376+
depth
377+
) do
372378
{analysis, _in_defer} = check_defer_directive(node, config, analysis, depth)
373379
# Would need to look up the fragment definition for full analysis
374380
analysis

lib/absinthe/incremental/dataloader.ex

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,9 @@ defmodule Absinthe.Incremental.Dataloader do
127127
128128
This allows existing Dataloader resolvers to work with incremental delivery.
129129
"""
130-
@spec streaming_dataloader(atom(), any()) :: Resolution.resolver()
130+
@spec streaming_dataloader(atom(), any()) ::
131+
(Resolution.source(), Resolution.arguments(), Resolution.t() ->
132+
{:ok, any()} | {:error, any()} | {:middleware, module(), any()})
131133
def streaming_dataloader(source, batch_key \\ nil) do
132134
fn parent, args, %{context: context} = resolution ->
133135
# Check if we're in a streaming context
@@ -305,7 +307,7 @@ defmodule Absinthe.Incremental.Dataloader do
305307
}
306308

307309
# Add to the batch queue in the resolution context
308-
resolution =
310+
_resolution =
309311
update_in(
310312
resolution.context[:__dataloader_batch_queue__],
311313
&[batch_data | &1 || []]

lib/absinthe/incremental/error_handler.ex

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ defmodule Absinthe.Incremental.ErrorHandler do
66
streaming operations, ensuring robust behavior even when things go wrong.
77
"""
88

9-
alias Absinthe.Incremental.Response
109
require Logger
1110

1211
@type error_type ::
@@ -315,18 +314,11 @@ defmodule Absinthe.Incremental.ErrorHandler do
315314
}
316315
end
317316

318-
defp format_exception(exception, stacktrace \\ nil) do
319-
formatted_stacktrace =
320-
if stacktrace do
321-
Exception.format_stacktrace(stacktrace)
322-
else
323-
"stacktrace not available"
324-
end
325-
317+
defp format_exception(exception, stacktrace) do
326318
%{
327319
message: Exception.message(exception),
328320
type: exception.__struct__,
329-
stacktrace: formatted_stacktrace
321+
stacktrace: Exception.format_stacktrace(stacktrace)
330322
}
331323
end
332324

lib/absinthe/incremental/resource_manager.ex

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,16 @@ defmodule Absinthe.Incremental.ResourceManager do
258258
update_in(state.stream_stats.total_count, &(&1 + 1))
259259
end
260260

261+
defp update_stats(state, :stream_timeout) do
262+
state
263+
|> update_in([:stream_stats, :timeout_count], &(&1 + 1))
264+
|> update_in([:stream_stats, :failed_count], &(&1 + 1))
265+
end
266+
267+
defp update_stats(state, :stream_crashed) do
268+
update_in(state.stream_stats.failed_count, &(&1 + 1))
269+
end
270+
261271
defp update_stats(state, :stream_released, duration) do
262272
state
263273
|> update_in([:stream_stats, :completed_count], &(&1 + 1))
@@ -269,16 +279,6 @@ defmodule Absinthe.Incremental.ResourceManager do
269279
end)
270280
end
271281

272-
defp update_stats(state, :stream_timeout) do
273-
state
274-
|> update_in([:stream_stats, :timeout_count], &(&1 + 1))
275-
|> update_in([:stream_stats, :failed_count], &(&1 + 1))
276-
end
277-
278-
defp update_stats(state, :stream_crashed) do
279-
update_in(state.stream_stats.failed_count, &(&1 + 1))
280-
end
281-
282282
defp schedule_stream_timeout(operation_id, timeout_ms) do
283283
Process.send_after(self(), {:stream_timeout, operation_id}, timeout_ms)
284284
end

0 commit comments

Comments
 (0)