claudevdm commented on code in PR #39484:
URL: https://github.com/apache/beam/pull/39484#discussion_r3679221325


##########
sdks/python/container/profiler.go:
##########
@@ -334,3 +354,185 @@ func needsProcessing(binInfo os.FileInfo, path string) 
bool {
        // Don't regenerate when there were no updates to the profile.
        return binInfo.ModTime().After(info.ModTime())
 }
+
+func monitorCoredumpsLoop(ctx context.Context, logger *tools.Logger, pcfg 
*ProfilerConfig) {
+       // We require the core file pattern to be configured as 
"/tmp/core.%e.%p" via pipeline
+       // options experiments (which is automatically set by the Python SDK). 
This ensures
+       // that core dumps are written in /tmp/ with a prefix matching "core.".
+       coreDir := "/tmp"
+       interval := 5 * time.Second
+       if pcfg.PostprocessIntervalSec > 0 {
+               interval = time.Duration(pcfg.PostprocessIntervalSec) * 
time.Second
+       }
+       logger.Printf(ctx, "Monitoring directory %s for core dumps matching 
prefix core. every %v", coreDir, interval)
+
+       ticker := time.NewTicker(interval)
+       defer ticker.Stop()
+
+       for {
+               select {
+               case <-ctx.Done():
+                       return
+               case <-ticker.C:
+                       processNewCoredumps(ctx, logger, pcfg, coreDir)
+                       if isProfilerDisengaged(pcfg) {
+                               return
+                       }
+               }
+       }
+}
+
+func processNewCoredumps(ctx context.Context, logger *tools.Logger, pcfg 
*ProfilerConfig, coreDir string) {
+       files, err := os.ReadDir(coreDir)
+       if err != nil {
+               return
+       }
+
+       prefix := "core."

Review Comment:
   Is it a bit broad to match on any file starting with core.? Maybe we can add 
a bit more validation/regex?



##########
sdks/python/container/profiler.go:
##########
@@ -334,3 +354,185 @@ func needsProcessing(binInfo os.FileInfo, path string) 
bool {
        // Don't regenerate when there were no updates to the profile.
        return binInfo.ModTime().After(info.ModTime())
 }
+
+func monitorCoredumpsLoop(ctx context.Context, logger *tools.Logger, pcfg 
*ProfilerConfig) {
+       // We require the core file pattern to be configured as 
"/tmp/core.%e.%p" via pipeline
+       // options experiments (which is automatically set by the Python SDK). 
This ensures
+       // that core dumps are written in /tmp/ with a prefix matching "core.".
+       coreDir := "/tmp"
+       interval := 5 * time.Second
+       if pcfg.PostprocessIntervalSec > 0 {
+               interval = time.Duration(pcfg.PostprocessIntervalSec) * 
time.Second
+       }
+       logger.Printf(ctx, "Monitoring directory %s for core dumps matching 
prefix core. every %v", coreDir, interval)
+
+       ticker := time.NewTicker(interval)
+       defer ticker.Stop()
+
+       for {
+               select {
+               case <-ctx.Done():
+                       return
+               case <-ticker.C:
+                       processNewCoredumps(ctx, logger, pcfg, coreDir)
+                       if isProfilerDisengaged(pcfg) {
+                               return

Review Comment:
   Is this a race with the 2s file-age guard in processNewCoredumps? With 
--profiler_stop_after_crash.
   
   Should we do a final synchronous sweep here that waits out the age guard 
(sleep >2s, re-run processNewCoredumps, sync results to GCS) before returning?



##########
sdks/python/container/profiler.go:
##########
@@ -334,3 +354,185 @@ func needsProcessing(binInfo os.FileInfo, path string) 
bool {
        // Don't regenerate when there were no updates to the profile.
        return binInfo.ModTime().After(info.ModTime())
 }
+
+func monitorCoredumpsLoop(ctx context.Context, logger *tools.Logger, pcfg 
*ProfilerConfig) {
+       // We require the core file pattern to be configured as 
"/tmp/core.%e.%p" via pipeline
+       // options experiments (which is automatically set by the Python SDK). 
This ensures
+       // that core dumps are written in /tmp/ with a prefix matching "core.".
+       coreDir := "/tmp"
+       interval := 5 * time.Second
+       if pcfg.PostprocessIntervalSec > 0 {
+               interval = time.Duration(pcfg.PostprocessIntervalSec) * 
time.Second
+       }
+       logger.Printf(ctx, "Monitoring directory %s for core dumps matching 
prefix core. every %v", coreDir, interval)
+
+       ticker := time.NewTicker(interval)
+       defer ticker.Stop()
+
+       for {
+               select {
+               case <-ctx.Done():
+                       return
+               case <-ticker.C:
+                       processNewCoredumps(ctx, logger, pcfg, coreDir)

Review Comment:
   Should we syncProfilesToGCS here if the write was success?



##########
sdks/python/container/profiler.go:
##########
@@ -334,3 +354,185 @@ func needsProcessing(binInfo os.FileInfo, path string) 
bool {
        // Don't regenerate when there were no updates to the profile.
        return binInfo.ModTime().After(info.ModTime())
 }
+
+func monitorCoredumpsLoop(ctx context.Context, logger *tools.Logger, pcfg 
*ProfilerConfig) {
+       // We require the core file pattern to be configured as 
"/tmp/core.%e.%p" via pipeline
+       // options experiments (which is automatically set by the Python SDK). 
This ensures
+       // that core dumps are written in /tmp/ with a prefix matching "core.".
+       coreDir := "/tmp"
+       interval := 5 * time.Second

Review Comment:
   Is the default meant to be 5 seconds? It seems the pipeline option defaults 
to 60 sec 
https://github.com/apache/beam/blob/58bac320ebd2601e6b66261b5e40a72d59161cff/sdks/python/apache_beam/options/pipeline_options.py#L1724-L1726
   
   So the 5 seconds will only survive if someone explicitly sets the pipeline 
option to 0, otherwise it will default to 600 sec?
   
   Is 600 too long to catch segfault on startup?
   



##########
sdks/python/container/boot.go:
##########


Review Comment:
   The last crash's core dump seems to depend on the ticker firing before 
Fatalf exits the container (default interval is 600s, and fresh cores <2s old 
are skipped).
   
   Should we do one explicit core-dump sweep + GCS sync right before failing 
the container, so the crash that killed the worker is always analyzed 
regardless of timer timing?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to