-
Notifications
You must be signed in to change notification settings - Fork 14
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
Feature: Added creating of Directed Acyclic Graphs (DAG) to existing DAG Driver #433
base: main
Are you sure you want to change the base?
Conversation
d9e9ef0
to
9161a77
Compare
@leokondrashov: Is this still relevant or we close this PR? |
I apologize for the late reply. I will review this pull request! |
d75890a
to
fca5d95
Compare
a8f5730
to
3357247
Compare
cbc9203
to
e35a93e
Compare
Dear @cvetkovic, The current version looks good to me. However, due to my limited experience in reviewing pull requests, I would greatly appreciate it if you could provide us with some feedback when you have a moment. Thank you very much! |
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. @leokondrashov If good, you can proceed with merging.
@wanghanchengchn Just fix the errors linter reports. |
Thank you! Dear @NotAnAddictz, could you please address the failed checks? Additionally, this branch is out-of-date with the base branch. Kindly rebase on the main branch and verify that all checks are passing. Thank you! |
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.
Looks good to me codewise. But I'd like to have documentation for the feature in the repo, not only in the PR description.
I think the linter problem is not caused by you, but it's easy to fix by changing Fatalf
to Fatal
.
9ce8318
to
1a46497
Compare
32aad01
to
1e5e1de
Compare
pkg/generator/dag_generation.go
Outdated
var width,depth int | ||
DAGDistribution := generateCDF(fmt.Sprintf("%s/dag_structure.csv", config.TracePath)) | ||
totalLinkedList := []*list.List{} | ||
for _, function := range functions { |
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.
So, you generate the DAG for each function in the trace, right? But then, if we have > 1 function in the DAG, we would have functions that are invoked from different DAGs. It doesn't seem to be appropriate.
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.
Noted, after discussing with Hancheng, I will change the workflow to generate a single DAG only, based on the given parameters. And add a parameter to determine the entry function in the config file.
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 only one? IIRC, the DAGs are quite small on average. So even if we have 2k functions deployed, it would use only a handful. Can you continue to generate DAGs until it won't be able to fit another one? That seems more appropriate.
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.
Thanks for the suggestion. Have made it continuously generate DAGs. The entry function will start at index 0, with the next DAG's entry function being the next unused function. (ie: DAG 1 uses f(0) -> f(1) ->f(2). DAG 2 will have entry function f(3)). Invocation Frequencies and IAT will follow the respective entry function. DAGs will have different shapes based on dag_structure.csv unless user specifies with EnableDAGDataset
.
88da705
to
52d652e
Compare
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.
The code looks good to me. I have a couple of suggestions for tests: failure to generate, correct depth and width of bigger DAGs with multiple branches, reading and generating the sizes from trace file, creation of several DAGs.
734925b
to
7729de4
Compare
Thanks for the suggestions! Have added tests to generate from trace, multiple DAG generation of bigger DAGs (width = 10, depth 5) |
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.
Please fix couple minor things
pkg/driver/trace_driver.go
Outdated
if d.Configuration.LoaderConfiguration.AsyncMode { | ||
sleepFor := time.Duration(d.Configuration.LoaderConfiguration.AsyncWaitToCollectMin) * time.Minute | ||
|
||
log.Infof("Sleeping for %v...", sleepFor) | ||
time.Sleep(sleepFor) | ||
|
||
d.writeAsyncRecordsToLog(globalMetricsCollector) | ||
} | ||
|
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.
Duplicated lines, look above
pkg/driver/trace_driver.go
Outdated
node = node.Next() | ||
} | ||
atomic.AddInt64(metadata.FunctionsInvoked, numberOfFunctionsInvoked) | ||
if success { | ||
atomic.AddInt64(metadata.SuccessCount, 1) |
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.
This now counts successful branch execution, not DAG or functions. I don't think that would be the correct behaviour.
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.
Noted, have changed to reflect successful functions invoked.
pkg/driver/trace_driver_test.go
Outdated
RecordOutputChannel: invocationRecordOutputChannel, | ||
AnnounceDoneWG: announceDone, | ||
} | ||
|
||
announceDone.Add(1) | ||
testDriver.invokeFunction(metadata) | ||
if !(successCount == 1 && failureCount == 0) { | ||
announceDone.Wait() | ||
if !(functionsInvoked == 3 && failureCount == 0) { |
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.
Consider adding the successCount test as well. I think it might be handled wrongly (see previous comment).
@@ -135,7 +136,7 @@ func TestInvokeFunctionFromDriver(t *testing.T) { | |||
|
|||
testDriver := createTestDriver() | |||
var failureCountByMinute = make([]int64, testDriver.Configuration.TraceDuration) | |||
|
|||
var functionsInvoked int64 |
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.
Please also add it into test conditions.
docs/configuration.md
Outdated
@@ -33,7 +33,10 @@ | |||
| MetricScrapingPeriodSeconds | int | > 0 | 15 | Period of Prometheus metrics scrapping | | |||
| GRPCConnectionTimeoutSeconds | int | > 0 | 60 | Timeout for establishing a gRPC connection | | |||
| GRPCFunctionTimeoutSeconds | int | > 0 | 90 | Maximum time given to function to execute[^5] | | |||
| DAGMode | bool | true/false | false | Sequential invocation of all functions one after another | | |||
| DAGMode | bool | true/false | false | Generates DAG workflows iteratively with functions in TracePath [^7]. Frequency and IAT of the DAG follows their respective entry function, while Duration and Memory of each function will follow their respective values in TracePath. | | |||
| EnableDAGDataset | bool | true/false | true | Generate width and depth from data/traces/example/dag_structure.csv[^8] | |
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.
Update that the generation will take the .csv file from the trace path, not from that specific one. This one is the sample, not the data that should be used in real experiments.
Signed-off-by: Kway Yi Shen <[email protected]>
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 now. Thank you, YiShen, for patiently following all my suggestions.
@cvetkovic We would need to plan the merge around the merge of RPS mode. Can you assist in that?
@NotAnAddictz Unfortunately, this might require another rebase of the trace driver. But it should be pretty small because the RPS mode mostly changes the functionsDriver, while yours is mostly in the invoker part.
Summary
Previously, in PR #383 , we added functionality for sequential invocation for each function. This commit adds on to this existing feature, making every function act as an entry point and create a DAG structure for each function based on the width and depth distributions in
data/traces/example/dag_structure.xlsx
and invoke it according to the frequency of the entry functions.Implementation Notes ⚒️
sampled_150
folder containing the folders for each group of functions if required.Nodes
to facilitate DAG generationentriesWritten
to functionsDriver to ensure all invocations are written in the output fileExternal Dependencies 🍀
Breaking API Changes⚠️
Simply specify none (N/A) if not applicable.