66┌──────────────────────────────────────────┐
77│ Application Initialization │
88│ - Create resolver context │
9- │ - Form MFA : {Mod, :resolve, [context]} │
9+ │ - Form resolver : {Mod, [context]} │
1010└──────────────┬───────────────────────────┘
1111 │
1212 ▼
1313┌──────────────────────────────────────────┐
1414│ Enactment Initialization │
15- │ - Receives resolver_mfa │
15+ │ - Receives resolver config │
1616│ - Stores in enactment state │
1717└──────────────┬───────────────────────────┘
1818 │
@@ -100,44 +100,44 @@ defmodule ColouredFlow.Runtime.ModuleResolver do
100100 # ... behaviour definition ...
101101
102102 @typedoc """
103- Module resolver in MFA form .
103+ Module resolver configuration .
104104
105105 The tuple contains:
106106 - module: Module implementing ModuleResolver behaviour
107- - function: Always :resolve
108107 - args: List containing [context] (pre-initialized)
109108
110- When calling: apply(module, :resolve, [module_ref, context, runtime_info])
109+ Since the behaviour defines resolve/3, the function name is implicit.
110+ When calling: apply(module, :resolve, [module_ref] ++ args ++ [runtime_info])
111111 """
112- @type mfa () :: {module (), :resolve , [context ()]}
112+ @type resolver () :: {module (), [context ()]}
113113
114114 @doc """
115- Helper to create MFA from resolver module and context.
115+ Helper to create resolver configuration from module and context.
116116
117117 ## Examples
118118
119119 context = MyResolver.init(repo: MyApp.Repo)
120- mfa = ModuleResolver.to_mfa (MyResolver, context)
121- # Returns: {MyResolver, :resolve, [context]}
120+ resolver = ModuleResolver.new (MyResolver, context)
121+ # Returns: {MyResolver, [context]}
122122 """
123- @spec to_mfa (module (), context ()) :: mfa ()
124- def to_mfa (resolver_module, context) when is_atom (resolver_module) do
125- {resolver_module, :resolve , [context]}
123+ @spec new (module (), context ()) :: resolver ()
124+ def new (resolver_module, context) when is_atom (resolver_module) do
125+ {resolver_module, [context]}
126126 end
127127
128128 @doc """
129- Helper to call MFA with module reference and runtime info.
129+ Call resolver with module reference and runtime info.
130130
131131 ## Examples
132132
133- mfa = {MyResolver, :resolve , [context]}
133+ resolver = {MyResolver, [context]}
134134 runtime_info = %{enactment_id: 123}
135- {:ok, module} = ModuleResolver.call_mfa(mfa , module_ref, runtime_info)
135+ {:ok, module} = ModuleResolver.resolve(resolver , module_ref, runtime_info)
136136 """
137- @spec call_mfa ( mfa (), module_ref (), runtime_info ()) ::
137+ @spec resolve ( resolver (), module_ref (), runtime_info ()) ::
138138 {:ok , Module .t ()} | {:error , term ()}
139- def call_mfa ({module, :resolve , [context]}, module_ref, runtime_info) do
140- apply (module , :resolve , [module_ref, context, runtime_info])
139+ def resolve ({resolver_module , [context]}, module_ref, runtime_info) do
140+ apply (resolver_module , :resolve , [module_ref, context, runtime_info])
141141 end
142142end
143143```
@@ -305,12 +305,12 @@ end
305305
306306# 1. Application level: Initialize resolver
307307resolver_context = ModuleResolver .Default .init (repo: MyApp .Repo )
308- resolver_mfa = ModuleResolver .to_mfa (ModuleResolver .Default , resolver_context)
308+ resolver = ModuleResolver .new (ModuleResolver .Default , resolver_context)
309309
310310# 2. Pass to enactment
311311{:ok , enactment_pid} = Enactment .start_link (
312312 cpnet: cpnet,
313- resolver: resolver_mfa ,
313+ resolver: resolver ,
314314 # ... other options
315315)
316316
@@ -319,7 +319,7 @@ defmodule ColouredFlow.Runner.Enactment do
319319 def init (opts) do
320320 state = %{
321321 cpnet: opts[:cpnet ],
322- resolver_mfa : opts[:resolver ],
322+ resolver : opts[:resolver ],
323323 enactment_id: generate_id (),
324324 # ...
325325 }
@@ -334,7 +334,7 @@ defmodule ColouredFlow.Runner.Enactment do
334334 parent_transition: transition.name
335335 }
336336
337- case ModuleResolver .call_mfa (state.resolver_mfa , transition.subst, runtime_info) do
337+ case ModuleResolver .resolve (state.resolver , transition.subst, runtime_info) do
338338 {:ok , module} ->
339339 # Use the resolved module
340340 execute_module (module, .. .)
@@ -359,10 +359,10 @@ defmodule MyApp.Application do
359359 def start (_type , _args ) do
360360 # Initialize resolver
361361 resolver_context = ModuleResolver .Default .init (repo: MyApp .Repo )
362- resolver_mfa = ModuleResolver .to_mfa (ModuleResolver .Default , resolver_context)
362+ resolver = ModuleResolver .new (ModuleResolver .Default , resolver_context)
363363
364364 # Store in application env or pass to supervisor
365- Application .put_env (:my_app , :module_resolver , resolver_mfa )
365+ Application .put_env (:my_app , :module_resolver , resolver )
366366
367367 # Start supervisors...
368368 end
@@ -388,15 +388,21 @@ cpnet = %ColouredPetriNet{
388388}
389389
390390# 3. Start enactment with resolver
391- resolver_mfa = Application .get_env (:my_app , :module_resolver )
391+ resolver = Application .get_env (:my_app , :module_resolver )
392392
393393{:ok , enactment_pid} = Enactment .start_link (
394394 cpnet: cpnet,
395- resolver: resolver_mfa ,
395+ resolver: resolver ,
396396 initial_marking: [.. .]
397397)
398398
399399# 4. When transition fires, enactment calls:
400+ # ModuleResolver.resolve(
401+ # {ModuleResolver.Default, [resolver_context]},
402+ # {:module_ref, flow_id: 123, port_specs: [...]},
403+ # %{enactment_id: "abc123", parent_transition: "authenticate"}
404+ # )
405+ # Which internally does:
400406# apply(ModuleResolver.Default, :resolve, [
401407# {:module_ref, flow_id: 123, port_specs: [...]},
402408# resolver_context,
@@ -412,10 +418,11 @@ resolver_mfa = Application.get_env(:my_app, :module_resolver)
4124184 . ** Testable** : Easy to mock MFA in tests
4134195 . ** Flexible** : Can use different resolvers for different enactments
414420
415- ## Key Changes from Previous Design
421+ ## Key Design Points
416422
417- 1 . ** Behaviour signature** : ` resolve/3 ` instead of ` resolve/2 `
423+ 1 . ** Behaviour signature** : ` resolve/3 ` with module_ref, context, runtime_info
4184242 . ** Third parameter** : ` runtime_info ` with enactment context
419- 3 . ** MFA format** : ` {Module, :resolve, [context]} ` for easy passing
420- 4 . ** Helper functions** : ` to_mfa /2` and ` call_mfa /3` for convenience
425+ 3 . ** Resolver format** : ` {Module, [context]} ` - function name implicit from behaviour
426+ 4 . ** Helper functions** : ` new /2` and ` resolve /3` for convenience
4214275 . ** Lazy loading** : Resolution happens at runtime, not upfront
428+ 6 . ** No redundancy** : Function name omitted since behaviour defines it
0 commit comments