You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
base_instance.ex # Ash Fragment for Instance resources
44
45
base_party.ex # Ash Fragment for Party resources
45
46
base_place.ex # Ash Fragment for Place resources
46
47
components/
47
48
base_characteristic.ex # Ash Fragment for typed characteristic resources
49
+
base_relationship.ex # Ash Fragment for shared Relationship structure
48
50
calculations/
49
51
characteristic_value.ex # Calculation: builds .Value TypedStruct from record fields
50
52
assigned_values.ex # Calculation: returns list of assigned integers for a pool+thing
@@ -162,6 +164,9 @@ mix test --max-failures 5 # stop early
162
164
- Using the removed `AssignableValue` TypedStruct — it no longer exists; use `pools do`.
163
165
- Calling `Assigner.assign/4` when a `pools do` declaration exists — prefer `Assigner.assign/3` which looks up the thing automatically.
164
166
- Forgetting to call `Pool.update_pools/3` in `:define` actions when the resource has `pools do` — pool bounds (`first`, `last`, `algorithm`) are set here.
167
+
- Using `characteristic :pool_name, Diffo.Provider.AssignedToRelationship` — `AssignedToRelationship` is not a characteristic; use `pools do / pool :name, :thing / end` instead.
168
+
- Querying `Diffo.Provider.Relationship` for assignment records — assignment relationships are on `Diffo.Provider.AssignedToRelationship`; access them via `instance.assignments`.
169
+
- Filtering `instance.forward_relationships` for `type == :assignedTo` — those records no longer exist there; use `instance.assignments` directly.
165
170
- Calling `build_before/1` or `build_after/2` in actions — these run automatically.
166
171
- Declaring `:specified_by`, `:features`, `:characteristics` as action arguments.
167
172
- Editing `documentation/dsls/DSL-Diffo.Provider.Extension.md` — it is Spark-generated;
Copy file name to clipboardExpand all lines: documentation/how_to/use_diffo_provider_extension.livemd
+7-7Lines changed: 7 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -153,7 +153,7 @@ arguments automatically onto that action.
153
153
154
154
Each characteristic is a dedicated Ash resource using the `Diffo.Provider.BaseCharacteristic` fragment. It carries direct typed attributes and a `:value` calculation that builds a companion `<Module>.Value` TypedStruct for ordered JSON encoding. The TypedStruct uses [AshJason.TypedStruct](https://hexdocs.pm/ash_jason/) to control field order in the JSON output.
155
155
156
-
For partial resource allocation and assignment we've created `Diffo.Provider.Assigner`. The host resource declares a `pools do` section listing each assignable pool by name and the kind of thing being assigned. Pool bounds (first/last value, algorithm) are set via a `:define` action. Assignment to Services or Resources is via `type: :assignedTo` Relationships that carry the assigned value directly on the Relationship node.
156
+
For partial resource allocation and assignment we've created `Diffo.Provider.Assigner`. The host resource declares a `pools do` section listing each assignable pool by name and the kind of thing being assigned. Pool bounds (first/last value, algorithm) are set via a `:define` action. Each assignment is stored as a `Diffo.Provider.AssignedToRelationship` node (Neo4j label `:AssignmentRelationship`) carrying `pool`, `thing`, and the `assigned` value. These are distinct from regular TMF `Diffo.Provider.Relationship` nodes and are accessible on an instance via `instance.assignments`.
157
157
158
158
Let's imagine a Compute domain which operates GPU and NPU resources. We want to expose a Cluster composite resource which can be dynamically composed of a number of GPU and NPU cores.
The `:cores` pool is backed by an `AssignableCharacteristic` node that records the range bounds and algorithm. Free cores are computed at assignment time from the count of existing `:assignedTo` relationships — there is no stored `free` counter. We can render one as json:
766
+
The `:cores` pool is backed by an `AssignableCharacteristic` node that records the range bounds and algorithm. Free cores are computed at assignment time from the count of existing `AssignmentRelationship` records — there is no stored `free` counter. We can render one as json:
Now our cluster should have a core from each GPU. Check in the Neo4j browser for `:assignedTo` Relationship nodes from `gpu_1` and `gpu_2` to `cluster_1`. There should be four — each Relationship carries `pool: :cores`, `thing: :core`, and the `assigned` integer value (e.g. 1, 2, 3 from gpu_1 and 1 from gpu_2).
786
+
Now our cluster should have a core from each GPU. Check in the Neo4j browser for `:AssignmentRelationship`nodes from `gpu_1` and `gpu_2` to `cluster_1`. There should be four — each carries `pool: :cores`, `thing: :core`, and the `assigned` integer value (e.g. 1, 2, 3 from gpu_1 and 1 from gpu_2).
787
787
788
-
The GPU's `forward_relationships` include each `:assignedTo` relationship, showing the assigned core number in the JSON encoding as a `resourceRelationshipCharacteristic`:
788
+
The GPU's `assignments` hold each assignment, showing the assigned core number in the JSON encoding as a `resourceRelationshipCharacteristic`:
789
789
790
790
```elixir
791
791
Jason.encode!(gpu_1, pretty:true) |>IO.puts
792
792
```
793
793
794
-
Make sure you have a look at it in the neo4j browser. There should be Relationship nodes with a role of :assignedTofrom each GPU resource instance to the cluster_1 resource instance. Each Relationship should be defined by a Characteristic with the assigned core number.
795
-
There is no central assignment table, rather the relationships ARE the assignments.
794
+
Make sure you have a look at it in the neo4j browser. There should be `:AssignmentRelationship` nodes from each GPU resource instance to the `cluster_1` resource instance, each carrying the assigned core number.
795
+
There is no central assignment table — the `AssignedToRelationship` nodes ARE the assignments. They are separate from the regular `:Relationship` nodes used for TMF service/resource relationships, and are accessible in Elixir via `instance.assignments`.
796
796
797
797
As an exercise, clone the GPU resource to create an NPU resource and assign some NPU cores from it to your cluster. Check that the assigned NPU cores are unique.
798
798
@@ -805,7 +805,7 @@ In this tutorial you've used Diffo's unified `provider do` extension to define a
805
805
806
806
- A composite Cluster resource that receives GPU cores via `Diffo.Provider.Assigner`
807
807
- A GPU resource using `pools do` to declare the `:cores` assignable pool — `pool :cores, :core` replaces the old `characteristic :cores, AssignableValue` pattern
808
-
-Assignment stored directly on `:assignedTo` Relationship nodes (no separate Characteristic nodes for assignments)
808
+
-Assignments stored on `Diffo.Provider.AssignedToRelationship`nodes (Neo4j label `:AssignmentRelationship`, distinct from TMF `:Relationship`nodes); accessible via `instance.assignments`
809
809
-`Tenant` and `Engineer` Party kinds declared with `provider do` that express which instances they operate and manage
810
810
- A `DataCentre` Place kind that declares the instances located at it
0 commit comments