mirror of
https://github.com/amir20/dozzle.git
synced 2025-12-24 06:28:42 +01:00
Reconnects if container starts running again (#1250)
* Cleans up code a little * Tries to reconnect if container starts again
This commit is contained in:
@@ -27,22 +27,22 @@
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot="{ setLoading }">
|
||||
<log-viewer-with-source :id="id" @loading-more="setLoading($event)"></log-viewer-with-source>
|
||||
<log-viewer-with-source :id="id" @loading-more="setLoading($event)" ref="source"></log-viewer-with-source>
|
||||
</template>
|
||||
</scrollable-view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from "vuex";
|
||||
|
||||
import LogViewerWithSource from "./LogViewerWithSource";
|
||||
import ScrollableView from "./ScrollableView";
|
||||
import ContainerTitle from "./ContainerTitle";
|
||||
import ContainerStat from "./ContainerStat";
|
||||
import Icon from "./Icon";
|
||||
import config from "../store/config";
|
||||
import containerMixin from "./mixins/container";
|
||||
|
||||
export default {
|
||||
mixins: [containerMixin],
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
@@ -69,10 +69,6 @@ export default {
|
||||
Icon,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(["allContainersById"]),
|
||||
container() {
|
||||
return this.allContainersById[this.id];
|
||||
},
|
||||
base() {
|
||||
return config.base;
|
||||
},
|
||||
|
||||
@@ -34,9 +34,17 @@ describe("<LogEventSource />", () => {
|
||||
localVue.component("log-viewer", LogViewer);
|
||||
|
||||
const state = { searchFilter, settings: { size: "medium", showTimestamp: true, hourStyle } };
|
||||
const getters = {
|
||||
allContainersById() {
|
||||
return {
|
||||
abc: { state: "running" },
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
const store = new Vuex.Store({
|
||||
state,
|
||||
getters,
|
||||
});
|
||||
|
||||
return mount(LogEventSource, {
|
||||
@@ -57,9 +65,10 @@ describe("<LogEventSource />", () => {
|
||||
});
|
||||
|
||||
test("should connect to EventSource", async () => {
|
||||
shallowMount(LogEventSource);
|
||||
const wrapper = createLogEventSource();
|
||||
sources["/api/logs/stream?id=abc"].emitOpen();
|
||||
expect(sources["/api/logs/stream?id=abc"].readyState).toBe(1);
|
||||
wrapper.destroy();
|
||||
});
|
||||
|
||||
test("should close EventSource", async () => {
|
||||
|
||||
@@ -9,9 +9,11 @@
|
||||
import debounce from "lodash.debounce";
|
||||
import InfiniteLoader from "./InfiniteLoader";
|
||||
import config from "../store/config";
|
||||
import containerMixin from "./mixins/container";
|
||||
|
||||
export default {
|
||||
props: ["id"],
|
||||
mixins: [containerMixin],
|
||||
name: "LogEventSource",
|
||||
components: {
|
||||
InfiniteLoader,
|
||||
@@ -24,13 +26,24 @@ export default {
|
||||
},
|
||||
created() {
|
||||
this.es = null;
|
||||
this.loadLogs(this.id);
|
||||
this.loadLogs();
|
||||
this.flushBuffer = debounce(this.flushNow, 250, { maxWait: 1000 });
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.es.close();
|
||||
},
|
||||
methods: {
|
||||
loadLogs(id) {
|
||||
onContainerStateChange(newValue, oldValue) {
|
||||
if (newValue == "running" && newValue != oldValue) {
|
||||
this.connect();
|
||||
}
|
||||
},
|
||||
loadLogs() {
|
||||
this.reset();
|
||||
this.es = new EventSource(`${config.base}/api/logs/stream?id=${id}`);
|
||||
this.connect();
|
||||
},
|
||||
connect() {
|
||||
this.es = new EventSource(`${config.base}/api/logs/stream?id=${this.id}`);
|
||||
this.es.addEventListener("container-stopped", (e) => {
|
||||
this.es.close();
|
||||
this.buffer.push({ event: "container-stopped", message: "Container stopped", date: new Date() });
|
||||
@@ -42,7 +55,6 @@ export default {
|
||||
this.buffer.push(this.parseMessage(e.data));
|
||||
this.flushBuffer();
|
||||
};
|
||||
this.$once("hook:beforeDestroy", () => this.es.close());
|
||||
},
|
||||
flushNow() {
|
||||
this.messages.push(...this.buffer);
|
||||
@@ -91,7 +103,7 @@ export default {
|
||||
watch: {
|
||||
id(newValue, oldValue) {
|
||||
if (oldValue !== newValue) {
|
||||
this.loadLogs(newValue);
|
||||
this.loadLogs();
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
19
assets/components/mixins/container.js
Normal file
19
assets/components/mixins/container.js
Normal file
@@ -0,0 +1,19 @@
|
||||
import { mapGetters } from "vuex";
|
||||
export default {
|
||||
computed: {
|
||||
...mapGetters(["allContainersById"]),
|
||||
container() {
|
||||
return this.allContainersById[this.id];
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
["container.state"](newValue, oldValue) {
|
||||
if (newValue == "running" && newValue != oldValue) {
|
||||
this.onContainerStateChange(newValue, oldValue);
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onContainerStateChange(newValue, oldValue) {},
|
||||
},
|
||||
};
|
||||
@@ -23,13 +23,12 @@ const mutations = {
|
||||
SET_CONTAINERS(state, containers) {
|
||||
const containersById = getters.allContainersById({ containers });
|
||||
|
||||
containers.forEach(
|
||||
(container) =>
|
||||
(container.stat =
|
||||
containersById[container.id] && containersById[container.id].stat
|
||||
? containersById[container.id].stat
|
||||
: { memoryUsage: 0, cpu: 0 })
|
||||
);
|
||||
containers.forEach((container) => {
|
||||
container.stat =
|
||||
containersById[container.id] && containersById[container.id].stat
|
||||
? containersById[container.id].stat
|
||||
: { memoryUsage: 0, cpu: 0 };
|
||||
});
|
||||
|
||||
state.containers = containers;
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user