1 2 3 4function CollectingRequestCache (debug = false, config = {}) 5{ 6 polling_calls = 10 7 polling_timeout = 500 8 intervall_timeout = 250 9 10 // load config 11 if (typeof config['polling_timeout'] != 'undefined') polling_timeout = config['polling_timeout'] 12 if (typeof config['polling_calls'] != 'undefined') polling_calls = config['polling_calls'] 13 if (typeof config['intervall_timeout'] != 'undefined') intervall_timeout = config['intervall_timeout'] 14 15 debug && console.log('init', [polling_calls, polling_timeout, intervall_timeout]) 16 17 18 var myCache = {} 19 /* idea not working 20 var resolvers = {} 21 var rejecters = {}*/ 22 var myQueue = [] 23 var registeredMethods = [] 24 var errors = {} 25 var intervallID = -1 26 27 function serialize (obj) 28 { 29 return JSON.stringify(obj) 30 } 31 32 function unserialize (str) 33 { 34 return JSON.parse(str) 35 } 36 37 function reStartSystem (){ 38 39 if(intervallID > -1){ 40 clearInterval(intervallID) 41 intervallID = -1 42 } 43 startSystem() 44 } 45 46 // core Caching system 47 function startSystem () 48 { 49 if (intervallID > -1) return 50 intervallID = setInterval(coreCall, intervall_timeout) 51 } 52 53 function coreCall(){ 54 { 55 debug && console.warn("CORE CALL TRIGGERED") 56 var runDone = false 57 debug && console.warn("intervall time is due") 58 Object.keys(registeredMethods).forEach(function (fnName) 59 { 60 debug && console.log("worker", fnName) 61 if (myQueue[fnName].length > 0) 62 { 63 runDone = true 64 // I have some job to do 65 66 var cachedIDs = [] 67 // TODO better use deep copy 68 myQueue[fnName].forEach(function (v) 69 { 70 cachedIDs.push(v) 71 }) 72 73 myQueue[fnName].splice(0, myQueue[fnName].length) 74 debug && console.log("worker with jobs:", cachedIDs) 75 76 // IF Error happend, we need to cache it and send it back, later on 77 registeredMethods[fnName](cachedIDs).then(function (results) 78 { 79 cachedIDs.forEach(function (v, i) 80 { 81 myCache[fnName][serialize(v)] = results[i] 82 /*console.log(resolvers[fnName][i]) 83 resolvers[fnName][i](results[i]) 84 rejecters[fnName].push(reject)*/ 85 }) // need to stringify this data 86 87 88 debug && console.log("some data loaded") 89 }).catch(function (error) 90 { 91 cachedIDs.forEach(function (v) 92 { 93 errors[fnName][serialize(v)] = error 94 //resolvers[fnName][i] 95 //rejecters[fnName][i](error) 96 }) // need to stringify this data 97 98 }) 99 100 101 102 } 103 104 }); 105 if(!runDone) { 106 clearInterval(intervallID) 107 intervallID = -1 108 } 109 110 } 111 } 112 113 114 115 function bufferedCacheAccess (fnName, payload, call) 116 { 117 return new Promise(function (resolve, reject) 118 { 119 120 if (Object.keys(myCache[fnName]).indexOf(serialize(payload)) > -1) 121 { 122 resolve(myCache[fnName][serialize(payload)]) 123 } 124 else if (Object.keys(errors[fnName]).indexOf(serialize(payload)) > -1) 125 { 126 reject(errors[fnName][serialize(payload)]) 127 } 128 else if (call >= polling_calls){ // TODO make it configurable 129 reject(`bufferedCacheAccess exceeded ${polling_calls} calls`); 130 } 131 else 132 { 133 setTimeout(function () 134 { 135 return bufferedCacheAccess(fnName, payload, call + 1).then(resolve).cat
135ch(reject) 136 }, polling_timeout) 137 } 138 139 140 }) 141 } 142 143 144 function get (fnName, payload) 145 { 146 reStartSystem(); 147 debug && console.log("Request fired", payload, myQueue[fnName].length) 148 if (Object.keys(registeredMethods).indexOf(fnName) == -1) 149 { 150 throw `Method ${fnName} is not registered` 151 } 152 153 // only if we need the data, we will set to fetch them, otherwise there is no need 154 if (Object.keys(myCache[fnName]).indexOf(serialize(payload)) == -1) 155 { 156 myQueue[fnName].push(payload) 157 delete errors[fnName][serialize(payload)] 158 } 159 160 return new Promise(function (resolve, reject) // resolve in ein Array packen 161 { 162 163 /*resolvers[fnName].push(resolve) 164 rejecters[fnName].push(reject)*/ 165 bufferedCacheAccess(fnName, payload, 0).then(resolve).catch(reject) 166 167 }) 168 } 169 170 171 function registerFn (fn) 172 { 173 debug && console.log(fn.name) 174 registeredMethods[fn.name] = fn 175 myCache[fn.name] = {} 176 myQueue[fn.name] = [] 177 errors[fn.name] = {} 178 //resolvers[fn.name] = [] 179 //rejecters[fn.name] = [] 180 181 } 182 183 return { 184 registerFn: registerFn, 185 get: get, 186 startSystem: startSystem, 187 reStartSystem: reStartSystem 188 } 189} 190 191 192// USER CODE HERE 193 194window.CollectingRequestCache = CollectingRequestCache(false, { 195 'polling_calls' : 40, 196 'polling_timeout': 250, 197 'intervall_timeout' : 250 198}) 199 200function loadStars (ids) 201{ 202 203 204 var config = { 205 method: "post", 206 url: `https://smartstats.kla.tv/v1/stats/list/?combined=true`, 207 timeout: 1000 * 10, 208 data: { 209 videoids: ids 210 } 211 } 212 213 214 return new Promise(function (resolve, reject) 215 { 216 axios(config).then(function (data) 217 { 218 var res = [] 219 var content = data['data']['data'] 220 221 ids.forEach(function (videoid) 222 { 223 res.push({ "data": { views: content['' + videoid] } }) 224 }) 225 resolve(res) 226 }).catch(reject) 227 228 }) 229} 230 231 232window.CollectingRequestCache.registerFn(loadStars) 233
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.