-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Add deal making trace #336
Conversation
ad172fd
to
ab54c02
Compare
7cd6cf3
to
d940b06
Compare
d940b06
to
6713b01
Compare
func GetResourceOfferIDs(resourceOffers []ResourceOffer) []string { | ||
var ids []string | ||
for _, offer := range resourceOffers { | ||
ids = append(ids, offer.ID) | ||
} | ||
return ids | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It may be confusing that that GetResourceOfferIDs
has a different behavior than GetResourceOfferID
. Open to naming suggestions.
} | ||
|
||
func (_ priceMismatch) matched() bool { return false } | ||
func (_ priceMismatch) message() string { | ||
return "fixed price job offer cannot afford resource offer" | ||
} | ||
func (result priceMismatch) attributes() []attribute.KeyValue { | ||
// If the module instruction price is not specified, this lookup will use the zero-value of 0 | ||
moduleInstructionPrice := result.resourceOffer.ModulePricing[result.moduleID].InstructionPrice |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't currently implement per module pricing, but this sets us up for it.
span.SetAttributes(attribute.KeyValue{ | ||
Key: "resource_offers", | ||
Value: attribute.StringSliceValue(data.GetResourceOfferContainerIDs(resourceOffers)), | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general, span attributes should be set when the span is created because they are generally considered static information. But we're setting them dynamically here as a part of the initialization leading up to the real work.
Setting these values as span attributes makes it easier to query spans with them.
_, matchSpan := tracer.Start(ctx, "match", | ||
trace.WithAttributes(attribute.String("job_offer.id", jobOffer.ID), | ||
attribute.String("resource_offer.id", resourceOffer.ID)), | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Future work. Would like to refactor this part of the algorithm out into a function. The change would make reading this code easier and we could avoid defining an child span in the scope of its parent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM and local testing worked. One question, but otherwise great work! 🎉
err: err, | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why did you move this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved it to access it in the price mismatch case:
lilypad/pkg/solver/matcher/match.go
Lines 269 to 273 in 60f45b4
return &priceMismatch{ | |
jobOffer: jobOffer, | |
resourceOffer: resourceOffer, | |
moduleID: moduleID, | |
} |
This price mismatch case is one scope out from where we were getting the module ID. Moving it avoids recomputing the module ID for this case.
Summary
This pull request makes the following changes:
solve
traceget_matching_deals
traceget_targeted_deal
tracematch
traceadd_deal
tracemoduleID
available one scope outThis pull request adds a trace to deal making in the solver. It observes matching and reports deals that were made and errors where a deal could not be made.
Preview image:
Task/Issue reference
Closes: #331
Test plan
Tracing over deal making includes a few spans:
solve
. The outermost parent span traces over thesolve
function.get_matching_deals
. Child of thesolve
trace.get_targeted_deal
. Child ofget_matching_deals
.match
. Child ofget_matching_deals
.Query for the
solve
span with:Add
span.deal_ids != "[]"
to filter out spans that did not match any deals:Adding this filter will helps with testing because
solve
runs every ten seconds, but only one trace will make a match for a test job run.The
get_matching_deals
span will appear as a child span. It can also be queried directly:Filtering with
span.job_offers != "[]"
ignores spans without any matches because they lack a job offer to match on.A
get_matching_deals
may contain one or morematch
spans. Eachmatch
span traces a match attempt between a job offer and a resource offer.When using node targeting, a
get_targeted_deal
span will appear as a child ofget_matching_deals
. This can be queried directly:Use this query to observe targeting attempts that fail when the requested target is not available.
Details
We use two different methods for tracing a function. When the function does not contain a child span, we wrap the call with
start
anddone
span events. For example:lilypad/pkg/solver/matcher/matcher.go
Lines 167 to 175 in fbc0382
When the function contains a child span, we simply call it passing the context and tracer. For example:
lilypad/pkg/solver/controller.go
Line 282 in fbc0382
The two approaches give us visibility on each function call, either as a pair of events in a span or a child span.
Related issues or PRs (optional)
Implements #75