)]}'
{"web/src/actions/logfile.js":[{"author":{"_account_id":1,"name":"James E. Blair","email":"jim@acmegating.com","username":"corvus"},"change_message_id":"506cfa1c2368db5300af0611c325ce1aba583280","unresolved":false,"context_lines":[{"line_number":54,"context_line":"}"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"export const fetchLogfileIfNeeded \u003d (tenant, buildId, file, force) \u003d\u003e (dispatch, getState) \u003d\u003e {"},{"line_number":57,"context_line":"  dispatch(fetchBuild(tenant, buildId, getState(), force))"},{"line_number":58,"context_line":"    .then(() \u003d\u003e {"},{"line_number":59,"context_line":"      dispatch(fetchBuildManifest(buildId, getState()))"},{"line_number":60,"context_line":"        .then(() \u003d\u003e {"}],"source_content_type":"text/javascript","patch_set":4,"id":"7faddb67_4d507b33","line":57,"updated":"2019-07-24 16:20:03.000000000","message":"Oh, I made a change to that method so that performs the check internally.  I did that because otherwise it\u0027s hard to chain these together like this.  I wanted it to be so that we would fetch the build if needed, then fetch the manifest if needed, then fetch the logfile if needed.  So we can just call all three of these, and they will check internally (we pass the force parameter in too).  They return a promise which is fulfilled immediately if nothing needs to be done, so that this moves on to the next step.\n\nThis is all because if you hit the build page first, you\u0027ll get the build info, then the manifest and job output.  So if you then go to the log viewer page, you only need to fetch the logfile. But if someone sends you a deep link to a log viewer, you\u0027ll get the build info, the manifest and logfile.  Then if you go back to the build page, you only need to fetch the build output.\n\nI just noticed I forgot to add the force argument to fetchBuildManifest here, so that needs to be updated.","commit_id":"a624f80456757802d28f728539fb5a3a940914f6"},{"author":{"_account_id":9311,"name":"Tristan Cacqueray","email":"tdecacqu@redhat.com","username":"tristanC"},"change_message_id":"d4c257b6c07fc6a74b96596f71935bffc482fd40","unresolved":false,"context_lines":[{"line_number":54,"context_line":"}"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"export const fetchLogfileIfNeeded \u003d (tenant, buildId, file, force) \u003d\u003e (dispatch, getState) \u003d\u003e {"},{"line_number":57,"context_line":"  dispatch(fetchBuild(tenant, buildId, getState(), force))"},{"line_number":58,"context_line":"    .then(() \u003d\u003e {"},{"line_number":59,"context_line":"      dispatch(fetchBuildManifest(buildId, getState()))"},{"line_number":60,"context_line":"        .then(() \u003d\u003e {"}],"source_content_type":"text/javascript","patch_set":4,"id":"7faddb67_ed5847fb","line":57,"range":{"start_line":57,"start_character":11,"end_line":57,"end_character":21},"updated":"2019-07-24 16:05:44.000000000","message":"Perhaps we should check if the build is already fetched using fetchBuildIfNeeded.","commit_id":"a624f80456757802d28f728539fb5a3a940914f6"},{"author":{"_account_id":9311,"name":"Tristan Cacqueray","email":"tdecacqu@redhat.com","username":"tristanC"},"change_message_id":"1892272a7d874df9469dbdae383f5e5521356057","unresolved":false,"context_lines":[{"line_number":54,"context_line":"}"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"export const fetchLogfileIfNeeded \u003d (tenant, buildId, file, force) \u003d\u003e (dispatch, getState) \u003d\u003e {"},{"line_number":57,"context_line":"  dispatch(fetchBuild(tenant, buildId, getState(), force))"},{"line_number":58,"context_line":"    .then(() \u003d\u003e {"},{"line_number":59,"context_line":"      dispatch(fetchBuildManifest(buildId, getState()))"},{"line_number":60,"context_line":"        .then(() \u003d\u003e {"}],"source_content_type":"text/javascript","patch_set":4,"id":"7faddb67_22a0a9a5","line":57,"in_reply_to":"7faddb67_4d507b33","updated":"2019-07-24 17:45:43.000000000","message":"Ok, then a follow-up could merge fetchBuildIfNeeded with fetchBuild for consistency.","commit_id":"a624f80456757802d28f728539fb5a3a940914f6"},{"author":{"_account_id":9311,"name":"Tristan Cacqueray","email":"tdecacqu@redhat.com","username":"tristanC"},"change_message_id":"d4c257b6c07fc6a74b96596f71935bffc482fd40","unresolved":false,"context_lines":[{"line_number":59,"context_line":"      dispatch(fetchBuildManifest(buildId, getState()))"},{"line_number":60,"context_line":"        .then(() \u003d\u003e {"},{"line_number":61,"context_line":"          dispatch(fetchLogfile(buildId, file, getState(), force))"},{"line_number":62,"context_line":"        })"},{"line_number":63,"context_line":"    })"},{"line_number":64,"context_line":"}"}],"source_content_type":"text/javascript","patch_set":4,"id":"7faddb67_ad724f7b","line":62,"updated":"2019-07-24 16:05:44.000000000","message":"Similarly, we could use fetch.*IfNeeded method here too.","commit_id":"a624f80456757802d28f728539fb5a3a940914f6"}],"web/src/containers/build/Build.jsx":[{"author":{"_account_id":1,"name":"James E. Blair","email":"jim@acmegating.com","username":"corvus"},"change_message_id":"506cfa1c2368db5300af0611c325ce1aba583280","unresolved":false,"context_lines":[{"line_number":89,"context_line":"      \u003cPanel\u003e"},{"line_number":90,"context_line":"        \u003cPanel.Heading\u003eBuild result {build.uuid}\u003c/Panel.Heading\u003e"},{"line_number":91,"context_line":"        \u003cPanel.Body\u003e"},{"line_number":92,"context_line":"          \u003cTabContainer id\u003d\"zuul-project\" defaultActiveKey\u003d{1}\u003e"},{"line_number":93,"context_line":"            \u003cdiv\u003e"},{"line_number":94,"context_line":"              \u003cNav bsClass\u003d\"nav nav-tabs nav-tabs-pf\"\u003e"},{"line_number":95,"context_line":"                \u003cNavItem eventKey\u003d{1}\u003e"}],"source_content_type":"text/jsx","patch_set":4,"id":"7faddb67_ed44c776","line":92,"updated":"2019-07-24 16:20:03.000000000","message":"That\u0027s how I did it at first, but I thought the page was getting kind of long -- it keeps pushing the hosts/tasks summary down the page, but I think that\u0027s really important.  90% of the time, it\u0027s going to just tell you what\u0027s wrong with the job.  I felt like the tabs idea makes all of the important tools more accessible.\n\nI agree, if we keep tabs, we should have back return to the correct tab.  I haven\u0027t figured that out yet.","commit_id":"a624f80456757802d28f728539fb5a3a940914f6"},{"author":{"_account_id":9311,"name":"Tristan Cacqueray","email":"tdecacqu@redhat.com","username":"tristanC"},"change_message_id":"d4c257b6c07fc6a74b96596f71935bffc482fd40","unresolved":false,"context_lines":[{"line_number":89,"context_line":"      \u003cPanel\u003e"},{"line_number":90,"context_line":"        \u003cPanel.Heading\u003eBuild result {build.uuid}\u003c/Panel.Heading\u003e"},{"line_number":91,"context_line":"        \u003cPanel.Body\u003e"},{"line_number":92,"context_line":"          \u003cTabContainer id\u003d\"zuul-project\" defaultActiveKey\u003d{1}\u003e"},{"line_number":93,"context_line":"            \u003cdiv\u003e"},{"line_number":94,"context_line":"              \u003cNav bsClass\u003d\"nav nav-tabs nav-tabs-pf\"\u003e"},{"line_number":95,"context_line":"                \u003cNavItem eventKey\u003d{1}\u003e"}],"source_content_type":"text/jsx","patch_set":4,"id":"7faddb67_8d9af36b","line":92,"range":{"start_line":92,"start_character":11,"end_line":92,"end_character":23},"updated":"2019-07-24 16:05:44.000000000","message":"We would need to keep track of the pane, when using \u0027back\u0027 from a logfile, the view resets to the first tab. Perhaps we should put the logtree between the job table and the hosts/tasks summary?","commit_id":"a624f80456757802d28f728539fb5a3a940914f6"},{"author":{"_account_id":9311,"name":"Tristan Cacqueray","email":"tdecacqu@redhat.com","username":"tristanC"},"change_message_id":"1892272a7d874df9469dbdae383f5e5521356057","unresolved":false,"context_lines":[{"line_number":89,"context_line":"      \u003cPanel\u003e"},{"line_number":90,"context_line":"        \u003cPanel.Heading\u003eBuild result {build.uuid}\u003c/Panel.Heading\u003e"},{"line_number":91,"context_line":"        \u003cPanel.Body\u003e"},{"line_number":92,"context_line":"          \u003cTabContainer id\u003d\"zuul-project\" defaultActiveKey\u003d{1}\u003e"},{"line_number":93,"context_line":"            \u003cdiv\u003e"},{"line_number":94,"context_line":"              \u003cNav bsClass\u003d\"nav nav-tabs nav-tabs-pf\"\u003e"},{"line_number":95,"context_line":"                \u003cNavItem eventKey\u003d{1}\u003e"}],"source_content_type":"text/jsx","patch_set":4,"id":"7faddb67_02afad94","line":92,"in_reply_to":"7faddb67_ed44c776","updated":"2019-07-24 17:45:43.000000000","message":"Maybe using a paneIndex in the Build component state. If the state is not kept when using back, then we could store the index in the queryString and push it to the browser history (similarly to what the builds page does with the filters).","commit_id":"a624f80456757802d28f728539fb5a3a940914f6"}],"web/src/reducers/logfile.js":[{"author":{"_account_id":1,"name":"James E. Blair","email":"jim@acmegating.com","username":"corvus"},"change_message_id":"506cfa1c2368db5300af0611c325ce1aba583280","unresolved":false,"context_lines":[{"line_number":27,"context_line":"  data: null"},{"line_number":28,"context_line":"}, action) \u003d\u003e {"},{"line_number":29,"context_line":"  switch (action.type) {"},{"line_number":30,"context_line":"    case LOGFILE_FETCH_REQUEST:"},{"line_number":31,"context_line":"      return update(state, {$merge: {isFetching: true,"},{"line_number":32,"context_line":"                                     url: action.url,"},{"line_number":33,"context_line":"                                     data: null}})"}],"source_content_type":"text/javascript","patch_set":4,"id":"7faddb67_0d4a837f","line":30,"updated":"2019-07-24 16:20:03.000000000","message":"I thought about that, but some of the logfiles are going to be huge, so I thought we should store only one at a time, otherwise if you browse several, we might use all the ram.","commit_id":"a624f80456757802d28f728539fb5a3a940914f6"},{"author":{"_account_id":9311,"name":"Tristan Cacqueray","email":"tdecacqu@redhat.com","username":"tristanC"},"change_message_id":"d4c257b6c07fc6a74b96596f71935bffc482fd40","unresolved":false,"context_lines":[{"line_number":27,"context_line":"  data: null"},{"line_number":28,"context_line":"}, action) \u003d\u003e {"},{"line_number":29,"context_line":"  switch (action.type) {"},{"line_number":30,"context_line":"    case LOGFILE_FETCH_REQUEST:"},{"line_number":31,"context_line":"      return update(state, {$merge: {isFetching: true,"},{"line_number":32,"context_line":"                                     url: action.url,"},{"line_number":33,"context_line":"                                     data: null}})"}],"source_content_type":"text/javascript","patch_set":4,"id":"7faddb67_adcecf80","line":30,"updated":"2019-07-24 16:05:44.000000000","message":"We might want to structure the logfile store using a map[url, data] so that we cache already fetched results.\n\nThis could also be used by the build.output which already cache the job-output.json.","commit_id":"a624f80456757802d28f728539fb5a3a940914f6"},{"author":{"_account_id":9311,"name":"Tristan Cacqueray","email":"tdecacqu@redhat.com","username":"tristanC"},"change_message_id":"1892272a7d874df9469dbdae383f5e5521356057","unresolved":false,"context_lines":[{"line_number":27,"context_line":"  data: null"},{"line_number":28,"context_line":"}, action) \u003d\u003e {"},{"line_number":29,"context_line":"  switch (action.type) {"},{"line_number":30,"context_line":"    case LOGFILE_FETCH_REQUEST:"},{"line_number":31,"context_line":"      return update(state, {$merge: {isFetching: true,"},{"line_number":32,"context_line":"                                     url: action.url,"},{"line_number":33,"context_line":"                                     data: null}})"}],"source_content_type":"text/javascript","patch_set":4,"id":"7faddb67_e2829100","line":30,"in_reply_to":"7faddb67_0d4a837f","updated":"2019-07-24 17:45:43.000000000","message":"I think there are middleware to deal with that. Or when reducing, we could manually walk the store and delete old \u0026 heavy log files.\n\nHaving the files in the store would help if we want to display the file content inlined in the tree view. Though that could be improved in a followup.","commit_id":"a624f80456757802d28f728539fb5a3a940914f6"},{"author":{"_account_id":9311,"name":"Tristan Cacqueray","email":"tdecacqu@redhat.com","username":"tristanC"},"change_message_id":"12771d800c582ae84ef55c00668eed1d0d50aeea","unresolved":false,"context_lines":[{"line_number":27,"context_line":"  data: null"},{"line_number":28,"context_line":"}, action) \u003d\u003e {"},{"line_number":29,"context_line":"  switch (action.type) {"},{"line_number":30,"context_line":"    case LOGFILE_FETCH_REQUEST:"},{"line_number":31,"context_line":"      return update(state, {$merge: {isFetching: true,"},{"line_number":32,"context_line":"                                     url: action.url,"},{"line_number":33,"context_line":"                                     data: null}})"}],"source_content_type":"text/javascript","patch_set":4,"id":"7faddb67_a32a3f7b","line":30,"in_reply_to":"7faddb67_9cd9af23","updated":"2019-07-26 12:49:59.000000000","message":"It should be fine to store, for example, a 50MB file in the redux store, what really slows down the browser is when it has to render that file. Thus I think we could limit the maximum size of the map, and perhaps force very large file to be opened in a new tab. e.g. a max size of 200MB should give plenty of room to cache most build\u0027s logs.\n\nIn any case, we could implement a client side filter logic to reduce the amount of text rendering. In that situation, I don\u0027t think we should worry about ringbuffer, unless the user click a \u003eGB log file.","commit_id":"a624f80456757802d28f728539fb5a3a940914f6"},{"author":{"_account_id":2,"name":"Monty Taylor","email":"mordred@inaugust.com","username":"mordred"},"change_message_id":"6fee30290a767e8e8d2513ebf2c814b3a98a7b56","unresolved":false,"context_lines":[{"line_number":27,"context_line":"  data: null"},{"line_number":28,"context_line":"}, action) \u003d\u003e {"},{"line_number":29,"context_line":"  switch (action.type) {"},{"line_number":30,"context_line":"    case LOGFILE_FETCH_REQUEST:"},{"line_number":31,"context_line":"      return update(state, {$merge: {isFetching: true,"},{"line_number":32,"context_line":"                                     url: action.url,"},{"line_number":33,"context_line":"                                     data: null}})"}],"source_content_type":"text/javascript","patch_set":4,"id":"7faddb67_9cd9af23","line":30,"in_reply_to":"7faddb67_e2829100","updated":"2019-07-25 22:59:13.000000000","message":"There\u0027s definitely a tradeoff here. Caching multiple files could be nice for switching around. However, for the large files streaming the contents and only storing what the user is actually looking at in ram is also potentially friendlier.\n\nMaybe a ringbuffer that holds anything we actually completely fetched, ditching older ones? But dont\u0027 store them if we only partially streamed a result?","commit_id":"a624f80456757802d28f728539fb5a3a940914f6"}]}
