Skip to content

Commit

Permalink
Merge branch 'dev/1.9.0' into enterprise
Browse files Browse the repository at this point in the history
  • Loading branch information
Kinplemelon committed Apr 28, 2024
2 parents aa3a180 + 2e32d8e commit ac5b812
Show file tree
Hide file tree
Showing 18 changed files with 1,413 additions and 144 deletions.
224 changes: 224 additions & 0 deletions src/hooks/Rule/rule/useDebugRule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
import { addTrace, deleteTrace, getTraceLog } from '@/api/diagnose'
import { applyRuleTest } from '@/api/ruleengine'
import useSyncPolling from '@/hooks/useSyncPolling'
import { TraceRecord } from '@/types/diagnose'
import { TraceEncodeType } from '@/types/enum'
import { BasicRule, RuleItem } from '@/types/rule'
import { cloneDeep, debounce, isArray, isEqual, isFunction, mergeWith, startCase } from 'lodash'
import moment from 'moment'
import type { Ref } from 'vue'
import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
import { useStore } from 'vuex'
import type { FormattedLog, LogItem } from './useFormatDebugLog'
import useFormatDebugLog from './useFormatDebugLog'

const BYTE_PER_PAGE = Math.pow(2, 30)

export default () => {
let traceName = ''

const logData = ref<FormattedLog>({})
const emptyLogData = () => {
logData.value = {}
}

const deleteCurrentTrace = async () => {
try {
if (traceName) {
await deleteTrace(traceName)
traceName = ''
window.removeEventListener('beforeunload', deleteCurrentTrace)
}
} catch (error) {
//
}
}
/**
* Create trace before get trace log
*/
const createTrace = async (ruleId: string) => {
try {
deleteCurrentTrace()
const nowTimestamp = new Date().getTime()
const oneDayLaterTimestamp = nowTimestamp + 24 * 60 * 60 * 1000
const traceData: TraceRecord = {
name: `DEBUG_RULE_${ruleId}_${moment().format('YYYYMMDD_HHmmssSSS')}`,
type: 'ruleid',
ruleid: ruleId,
payload_encode: TraceEncodeType.Text,
start_at: new Date().toISOString(),
end_at: new Date(oneDayLaterTimestamp).toISOString(),
formatter: 'json',
}
const { name } = await addTrace(traceData)
emptyLogData()
traceName = name
window.addEventListener('beforeunload', deleteCurrentTrace)
return Promise.resolve()
} catch (error) {
return Promise.reject(error)
}
}

const getLogItemTitle = (item: Record<string, any>) => {
return startCase(item.msg)
}
const { formatLog } = useFormatDebugLog()

let cbAfterPolling: undefined | ((log: string) => void) = undefined
const setCbAfterPolling = (cb: (logContent: string) => void) => {
cbAfterPolling = cb
}

const mergeCustomize = (arr1: Array<LogItem>, arr2: Array<LogItem>) => {
if (isArray(arr1) && isArray(arr2)) {
return arr1.concat(arr2)
}
}
const addNewLogToCurrentLog = (currentLog: FormattedLog, newLog: FormattedLog) => {
return mergeWith(currentLog, newLog, mergeCustomize)
}

let logLastPosition = 0
const getNewestLog = async () => {
try {
const { items, meta } = await getTraceLog(traceName, {
bytes: BYTE_PER_PAGE,
position: logLastPosition,
})
const data = formatLog(items)
logData.value = addNewLogToCurrentLog(logData.value, data)
logLastPosition = meta.position
if (isFunction(cbAfterPolling)) {
cbAfterPolling(items)
}
return Promise.resolve()
} catch (error) {
return Promise.reject()
//
}
}

const { needPolling, syncPolling } = useSyncPolling()
needPolling.value = false
const startPolling = () => {
syncPolling(getNewestLog, 1500)
}

/**
* If testing with mock data, poll after submitting mock data
*/
const startTestRuleUseMockData = (ruleId: string) => {
createTrace(ruleId)
}
const submitMockDataForTestRule = async (ruleId: string, data: Record<string, any>) => {
try {
await applyRuleTest(ruleId, data)
if (!needPolling.value) {
needPolling.value = true
startPolling()
}
} catch (error) {
//
}
}

/**
* If testing with real data, polling starts when clicking start test
*/
const startTestRuleUseRealData = (ruleId: string) => {
try {
createTrace(ruleId)
if (!needPolling.value) {
needPolling.value = true
startPolling()
}
} catch (error) {
//
}
}

const handleStopTest = () => {
deleteCurrentTrace()
needPolling.value = false
logLastPosition = 0
}

onUnmounted(() => {
if (needPolling.value) {
needPolling.value = false
}
deleteCurrentTrace()
})

return {
logData: logData,
emptyLogArr: emptyLogData,
handleStopTest,
getLogItemTitle,
startTestRuleUseMockData,
submitMockDataForTestRule,
startTestRuleUseRealData,
setCbAfterPolling,
}
}

export const useStatusController = (rule?: Ref<BasicRule | RuleItem>) => {
const { state, commit, getters } = useStore()
const isTesting = computed({
get() {
return state.isTesting
},
set(val) {
commit('SET_IS_TESTING', val)
},
})
const savedAfterRuleChange = computed({
get() {
return state.savedAfterRuleChange
},
set(val) {
commit('SET_SAVED_AFTER_RULE_CHANGE', val)
},
})
const testTarget = computed({
get() {
return state.testRuleTarget
},
set(val) {
commit('SET_TEST_RULE_TARGET', val)
},
})

const isRuleSaveButtonDisabled = computed(() => getters.isRuleSaveButtonDisabled)

const lastSavedRule: Ref<BasicRule | RuleItem | undefined> = ref(
(rule && rule.value) || undefined,
)
const updateSavedRule = (savedRule: BasicRule | RuleItem) => {
savedAfterRuleChange.value = isEqual(savedRule, rule?.value)
lastSavedRule.value = cloneDeep(savedRule)
}

const compareRuleAndUpdateSavedStatus = () => {
savedAfterRuleChange.value = isEqual(lastSavedRule.value, rule?.value)
}

const handleRuleChanged = debounce(compareRuleAndUpdateSavedStatus, 300)

if (rule) {
watch(rule, handleRuleChanged)
}

onMounted(() => {
isTesting.value = false
})

return {
isTesting,
savedAfterRuleChange,
testTarget,
isRuleSaveButtonDisabled,
updateSavedRule,
}
}
Loading

0 comments on commit ac5b812

Please sign in to comment.