Skip to content

Commit 3ce4762

Browse files
committed
feat: add job filter to memory client
When calling `ListJobs`, the filter can now be applied to the jobs. This supports all the filter options that are supported by the `ListJobs` method. It also makes a change to the DeleteJob method to perform a soft delete of the job, rather than a hard delete. This is in line with how the Job Distributor API works.
1 parent d35d8de commit 3ce4762

File tree

8 files changed

+1272
-320
lines changed

8 files changed

+1272
-320
lines changed

offchain/jd/memory/job_filter.go

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package memory
2+
3+
import (
4+
"slices"
5+
6+
jobv1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/job"
7+
"github.com/smartcontractkit/chainlink-protos/job-distributor/v1/shared/ptypes"
8+
)
9+
10+
// applyJobFilter applies the filter to the list of jobs and returns the filtered results.
11+
func applyJobFilter(
12+
jobs []*jobv1.Job, filter *jobv1.ListJobsRequest_Filter,
13+
) []*jobv1.Job {
14+
var filtered []*jobv1.Job
15+
16+
for _, job := range jobs {
17+
if jobMatchesFilter(job, filter) {
18+
filtered = append(filtered, job)
19+
}
20+
}
21+
22+
return filtered
23+
}
24+
25+
// jobMatchesFilter checks if a job matches the given filter criteria.
26+
func jobMatchesFilter(job *jobv1.Job, filter *jobv1.ListJobsRequest_Filter) bool {
27+
// Check if job is soft-deleted and should be excluded
28+
if !jobMatchesDeletedFilter(job, filter) {
29+
return false
30+
}
31+
32+
// Check job IDs
33+
if len(filter.Ids) > 0 {
34+
if !jobMatchesJobIds(job, filter.Ids) {
35+
return false
36+
}
37+
}
38+
39+
// Check UUIDs
40+
if len(filter.Uuids) > 0 {
41+
if !jobMatchesUuids(job, filter.Uuids) {
42+
return false
43+
}
44+
}
45+
46+
// Check node IDs
47+
if len(filter.NodeIds) > 0 {
48+
if !jobMatchesNodeIds(job, filter.NodeIds) {
49+
return false
50+
}
51+
}
52+
53+
// Check selectors
54+
if len(filter.Selectors) > 0 {
55+
for _, selector := range filter.Selectors {
56+
if !jobMatchesSelector(job, selector) {
57+
return false
58+
}
59+
}
60+
}
61+
62+
return true
63+
}
64+
65+
// jobMatchesJobIds checks if a job's ID is in the provided list of job IDs.
66+
func jobMatchesJobIds(job *jobv1.Job, jobIds []string) bool {
67+
return slices.Contains(jobIds, job.Id)
68+
}
69+
70+
// jobMatchesUuids checks if a job's UUID is in the provided list of UUIDs.
71+
func jobMatchesUuids(job *jobv1.Job, uuids []string) bool {
72+
return slices.Contains(uuids, job.Uuid)
73+
}
74+
75+
// jobMatchesNodeIds checks if a job's node ID is in the provided list of node IDs.
76+
func jobMatchesNodeIds(job *jobv1.Job, nodeIds []string) bool {
77+
return slices.Contains(nodeIds, job.NodeId)
78+
}
79+
80+
// jobMatchesDeletedFilter checks if a job should be included based on its deleted status.
81+
// By default, soft-deleted jobs (with DeletedAt set) are excluded unless IncludeDeleted is true.
82+
func jobMatchesDeletedFilter(job *jobv1.Job, filter *jobv1.ListJobsRequest_Filter) bool {
83+
// If job is soft-deleted (DeletedAt is not nil)
84+
if job.DeletedAt != nil {
85+
// Only include if IncludeDeleted is explicitly set to true
86+
return filter.IncludeDeleted
87+
}
88+
89+
// If job is not soft-deleted, always include it
90+
return true
91+
}
92+
93+
// jobMatchesSelector checks if a job matches a specific selector.
94+
func jobMatchesSelector(job *jobv1.Job, selector *ptypes.Selector) bool {
95+
// Get the job's labels as a map for easier lookup
96+
jobLabels := make(map[string]*string)
97+
for _, label := range job.Labels {
98+
jobLabels[label.Key] = label.Value
99+
}
100+
101+
return matchesSelector(jobLabels, selector)
102+
}

0 commit comments

Comments
 (0)