@@ -26,6 +26,37 @@ type ReplayProcessingChannelContents struct {
2626 ChunkOfFiles []string
2727}
2828
29+
30+ // writeResultsToSingleJSON handles stream writing to a single file
31+ func writeResultsToSingleJSON (outputDir string , input <- chan string ) {
32+ outputPath := filepath .Join (outputDir , "all_replays.json" )
33+ f , err := os .Create (outputPath )
34+ if err != nil {
35+ log .Error ("Failed to create output JSON file:" , err )
36+ // Drain channel to prevent blocking workers if file fails
37+ for range input {}
38+ return
39+ }
40+ defer f .Close ()
41+
42+ // Start the JSON array
43+ f .WriteString ("[\n " )
44+
45+ first := true
46+ for jsonString := range input {
47+ if ! first {
48+ f .WriteString (",\n " )
49+ }
50+ f .WriteString (jsonString )
51+ first = false
52+ }
53+
54+ // End the JSON array
55+ f .WriteString ("\n ]" )
56+ log .Info ("Successfully wrote combined JSON to " , outputPath )
57+ }
58+
59+
2960// PipelineWrapper is an orchestrator that distributes work
3061// among available workers (threads)
3162func PipelineWrapper (
@@ -51,6 +82,21 @@ func PipelineWrapper(
5182 )
5283 defer progressBar .Close ()
5384
85+
86+ // 1. Create the results channel
87+ singleJsonResultChan := make (chan string , cliFlags .NumberOfThreads * 4 )
88+
89+ // 2. Start the single writer goroutine
90+ var writerWg sync.WaitGroup
91+ // Creating a single writer gorouting that will create a single JSON file
92+ // with all of the replays as a JSON array.
93+ writerWg .Add (1 )
94+ go func () {
95+ defer writerWg .Done ()
96+ writeResultsToSingleJSON (cliFlags .OutputDirectory , singleJsonResultChan )
97+ }()
98+
99+
54100 // If it is specified by the user to perform the processing without
55101 // multiprocessing GOMAXPROCS needs to be set to 1 in order to allow 1 thread:
56102 runtime .GOMAXPROCS (cliFlags .NumberOfThreads )
@@ -59,13 +105,14 @@ func PipelineWrapper(
59105 // Adding a task for each of the supplied chunks to speed up the processing:
60106 wg .Add (cliFlags .NumberOfThreads )
61107
108+
62109 // Spin up workers waiting for chunks to process:
63110 for i := 0 ; i < cliFlags .NumberOfThreads ; i ++ {
64111 go func () {
112+ defer wg .Done ()
65113 for {
66114 channelContents , ok := <- channel
67115 if ! ok {
68- wg .Done ()
69116 return
70117 }
71118 MultiprocessingChunkPipeline (
@@ -76,6 +123,7 @@ func PipelineWrapper(
76123 foreignToEnglishMapping ,
77124 progressBar ,
78125 cliFlags ,
126+ singleJsonResultChan ,
79127 )
80128 }
81129 }()
@@ -91,6 +139,8 @@ func PipelineWrapper(
91139
92140 close (channel )
93141 wg .Wait ()
142+ close (singleJsonResultChan )
143+ writerWg .Wait ()
94144 progressBar .Close ()
95145
96146 log .Debug ("Finished PipelineWrapper()" )
@@ -107,6 +157,7 @@ func MultiprocessingChunkPipeline(
107157 englishToForeignMapping map [string ]string ,
108158 progressBar * progressbar.ProgressBar ,
109159 cliFlags utils.CLIFlags ,
160+ singleJsonResultChan chan <- string ,
110161) {
111162
112163 // Letting the orchestrator know that this processing task was finished:
@@ -204,8 +255,17 @@ func MultiprocessingChunkPipeline(
204255 return
205256 }
206257
258+ if cliFlags .SingleJsonOutput {
259+ singleJsonResultChan <- replayString
260+ processedCounter ++
261+ processingInfoStruct .AddToProcessed (replayFile )
262+ log .Info ("Sent file to writer for single JSON output." )
263+ return
264+ }
265+
266+
207267 // Saving output to zip archive:
208- if packageToZipBool {
268+ if packageToZipBool {
209269 // Append it to a list and when a package is created create a package summary and clear the list for next iterations
210270 persistent_data .AddReplaySummToPackageSumm (
211271 & replaySummary ,
@@ -217,7 +277,8 @@ func MultiprocessingChunkPipeline(
217277 replayString ,
218278 replayFile ,
219279 compressionMethod ,
220- writer )
280+ writer ,
281+ )
221282 if ! savedSuccess {
222283 compressionErrorCounter ++
223284 log .WithFields (log.Fields {
@@ -233,6 +294,7 @@ func MultiprocessingChunkPipeline(
233294 return
234295 }
235296
297+
236298 okSaveToDrive := file_utils .SaveReplayJSONFileToDrive (
237299 replayString ,
238300 replayFile ,
0 commit comments