0.1.6 improve logging and returns from snapshot, expose subtract and mb as part of class
parent
cd8dec5927
commit
be3611abf2
|
@ -1,18 +1,22 @@
|
||||||
import Memory from '../src/memory.js'
|
import Memory from '../src/memory.js'
|
||||||
|
|
||||||
const mem = new Memory({db:0})
|
const mem = new Memory({db:0}) // no debounce
|
||||||
|
|
||||||
// let text
|
// mem.watch(console.dir)
|
||||||
// mem.watch(console.log)
|
// mem.watch()
|
||||||
|
mem.watch( (stats) => {
|
||||||
mem.watch()
|
// console.log(stats)
|
||||||
|
console.log('remaining heap after garbage collection>>>',mem.subtract(stats.after.heapSizeLimit,stats.after.usedHeapSize))
|
||||||
|
})
|
||||||
|
|
||||||
setInterval(()=>
|
setInterval(()=>
|
||||||
mem.emit('tick')
|
mem.emit('tick')
|
||||||
,5000)
|
,5000)
|
||||||
|
|
||||||
mem.on('tick',()=> {
|
mem.on('tick',()=> {
|
||||||
mem.log({msg:'testing'})
|
// mem.clog({msg:'testing', props:'all', str:true})
|
||||||
|
// console.dir(mem.snapshot())
|
||||||
|
console.log('remaining heap at snapshot@@@@',mem.snapshot().remaining)
|
||||||
let text
|
let text
|
||||||
for (let i = 0; i < 1000000; i++) {
|
for (let i = 0; i < 1000000; i++) {
|
||||||
text += 'a'
|
text += 'a'
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@uci-utils/memory",
|
"name": "@uci-utils/memory",
|
||||||
"version": "0.1.5",
|
"version": "0.1.6",
|
||||||
"description": "memory logger and watcher",
|
"description": "memory logger and watcher",
|
||||||
"main": "src/memory.js",
|
"main": "src/memory.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
19
readme.md
19
readme.md
|
@ -1,18 +1 @@
|
||||||
# uCOMmandIt Reactive Class
|
# uCOMmandIt Memory Logging Utility
|
||||||
|
|
||||||
A Great Class to Extend! It has built in support to make reactive any/all class properties and their nested leaves.
|
|
||||||
|
|
||||||
## Why?
|
|
||||||
|
|
||||||
To have reactivity similar to vue and react but in any backend object?
|
|
||||||
This allow a backend app to maintain app settings and allow "clients" to get updated values when the app changes state. Essentially will create a 'mini' state event bus.
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
Will both emit and allow subscriptions to any property 'path' that has been made reactive.
|
|
||||||
|
|
||||||
Allows custom registration of unlimited state change event hooks.
|
|
||||||
|
|
||||||
Allows additional rxjs operators for the pipe the observer for each property.
|
|
||||||
|
|
||||||
See Examples folder
|
|
||||||
|
|
|
@ -25,14 +25,13 @@ const PROPS = Object.keys(STATS)
|
||||||
class Memory extends EventEmitter {
|
class Memory extends EventEmitter {
|
||||||
constructor(opts={}) {
|
constructor(opts={}) {
|
||||||
super()
|
super()
|
||||||
this._props = Object.keys(this.stats)
|
|
||||||
this._diff = {}
|
this._diff = {}
|
||||||
PROPS.forEach(prop=>this._diff[prop]={})
|
PROPS.forEach(prop=>this._diff[prop]={})
|
||||||
this._current = this.get()
|
this._current = this.get()
|
||||||
this.db = opts.db || 3000
|
this.db = opts.db || 3000 // debounce for gc watch
|
||||||
this.reset()
|
this.reset()
|
||||||
this.last = this.first
|
this.last = this.first
|
||||||
this.gc = gc()
|
this._watcher = false
|
||||||
}
|
}
|
||||||
|
|
||||||
get stats () {
|
get stats () {
|
||||||
|
@ -40,7 +39,7 @@ class Memory extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
sizeof (obj, u='M') {
|
sizeof (obj, u='M') {
|
||||||
return mb(sizeof(obj))
|
return this.mb(sizeof(obj))
|
||||||
}
|
}
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
|
@ -50,12 +49,12 @@ class Memory extends EventEmitter {
|
||||||
get() {
|
get() {
|
||||||
const mem = this.stats
|
const mem = this.stats
|
||||||
PROPS.forEach(prop => {
|
PROPS.forEach(prop => {
|
||||||
if (STATS[prop] === 'byte') mem[prop] = mb(mem[prop],2)
|
if (STATS[prop] === 'byte') mem[prop] = this.mb(mem[prop],2)
|
||||||
})
|
})
|
||||||
return mem
|
return mem
|
||||||
}
|
}
|
||||||
|
|
||||||
snapshot() {
|
snapshot(props,str) {
|
||||||
this.last=Object.assign({},this._current)
|
this.last=Object.assign({},this._current)
|
||||||
this._current=this.get()
|
this._current=this.get()
|
||||||
this.remaining = _.sub(this._current.heap_size_limit,this._current.used_heap_size)
|
this.remaining = _.sub(this._current.heap_size_limit,this._current.used_heap_size)
|
||||||
|
@ -65,28 +64,46 @@ class Memory extends EventEmitter {
|
||||||
this._diff[prop].overall=_.sub(this._current[prop],this.first[prop])
|
this._diff[prop].overall=_.sub(this._current[prop],this.first[prop])
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return { remaining:this.remaining, first:this.first, last:this.last, current:this._current, diff:this._diff }
|
if (props) {
|
||||||
|
if (typeof props ==='string') {
|
||||||
|
if (props === 'all') props = PROPS
|
||||||
|
else props = [props]
|
||||||
|
}
|
||||||
|
const strs = props.map(prop => this.log(prop) +'\n')
|
||||||
|
return str ? strs.join('') : strs
|
||||||
|
}
|
||||||
|
else return { remaining:this.remaining, first:this.first, last:this.last, current:this._current, diff:this._diff }
|
||||||
}
|
}
|
||||||
|
|
||||||
log (opts) {
|
clog (opts) {
|
||||||
this.snapshot()
|
let props = opts.props
|
||||||
|
if (!props) props = ['used_heap_size','number_of_native_contexts']
|
||||||
console.log(`============= ${opts.msg||''} =====================`,new Date().toLocaleString())
|
console.log(`============= ${opts.msg||''} =====================`,new Date().toLocaleString())
|
||||||
console.log(`remaining Heap: ${this.remaining} mb`)
|
console.log(`\n remaining Heap: ${this.remaining} mb \n`)
|
||||||
console.log(this._log('used_heap_size'))
|
console.log(this.snapshot(props,opts.str))
|
||||||
console.log(this._log('number_of_native_contexts'))
|
|
||||||
console.log(`============= ${opts.msg||''} =====================`)
|
console.log(`============= ${opts.msg||''} =====================`)
|
||||||
}
|
}
|
||||||
|
|
||||||
_log (prop) {
|
log (prop) {
|
||||||
return `${prop} > \
|
return `${prop} > \
|
||||||
diff:${this._diff[prop].overall}, \
|
diff:${this._diff[prop].overall}, \
|
||||||
lastdiff:${this._diff[prop].last}, \
|
lastdiff:${this._diff[prop].last}, \
|
||||||
current:${this._current[prop]}, \
|
current:${this._current[prop]}, \
|
||||||
last:${this.last[prop]}, \
|
last:${this.last[prop]}, \
|
||||||
first:${this.first[prop]}, \
|
first:${this.first[prop]} \
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
subtract (first,second,raw) {
|
||||||
|
const diff = _.sub(first,second)
|
||||||
|
return raw ? diff : this.mb(diff)
|
||||||
|
}
|
||||||
|
|
||||||
|
mb (val,p=2) {
|
||||||
|
// console.log(val,val / 1024 / 1024, _.round(val / 1024 / 1024, -p) )
|
||||||
|
return _.round(val / 1024 / 1024, -p)
|
||||||
|
}
|
||||||
|
|
||||||
// totalHeapSize: 17911808,
|
// totalHeapSize: 17911808,
|
||||||
// totalHeapExecutableSize: 573440,
|
// totalHeapExecutableSize: 573440,
|
||||||
// usedHeapSize: 13410032,
|
// usedHeapSize: 13410032,
|
||||||
|
@ -99,6 +116,10 @@ first:${this.first[prop]}, \
|
||||||
// numberOfDetachedContexts: 0
|
// numberOfDetachedContexts: 0
|
||||||
|
|
||||||
watch (handler) {
|
watch (handler) {
|
||||||
|
if (this._watcher) {
|
||||||
|
console.log('already watching, unwatch first to reset a handler')
|
||||||
|
return
|
||||||
|
}
|
||||||
gc().on('stats', dbfn(
|
gc().on('stats', dbfn(
|
||||||
stats => {
|
stats => {
|
||||||
const diff = _.sub(stats.after.heapSizeLimit,stats.after.usedHeapSize)
|
const diff = _.sub(stats.after.heapSizeLimit,stats.after.usedHeapSize)
|
||||||
|
@ -106,10 +127,10 @@ first:${this.first[prop]}, \
|
||||||
if (!handler) {
|
if (!handler) {
|
||||||
console.log(stats.gctype,'----------- Heap at GC ------------',new Date().toLocaleString())
|
console.log(stats.gctype,'----------- Heap at GC ------------',new Date().toLocaleString())
|
||||||
console.log(`Heap> \
|
console.log(`Heap> \
|
||||||
remaining: ${mb(diff)} mb \
|
remaining: ${this.mb(diff)} mb \
|
||||||
before:${mb(stats.before.usedHeapSize)}, \
|
before:${this.mb(stats.before.usedHeapSize)}, \
|
||||||
after:${mb(stats.after.usedHeapSize)} mb, \
|
after:${this.mb(stats.after.usedHeapSize)} mb, \
|
||||||
diff:${mb(stats.diff.usedHeapSize)} mb \
|
diff:${this.mb(stats.diff.usedHeapSize)} mb \
|
||||||
`)
|
`)
|
||||||
console.log('-----------------------')
|
console.log('-----------------------')
|
||||||
}
|
}
|
||||||
|
@ -117,15 +138,20 @@ diff:${mb(stats.diff.usedHeapSize)} mb \
|
||||||
}},
|
}},
|
||||||
{wait:this.db}
|
{wait:this.db}
|
||||||
)
|
)
|
||||||
)}
|
)
|
||||||
|
this._watcher = true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unwatch() {
|
||||||
|
gc().removeAllListeners('stats')
|
||||||
|
this._watcher = false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // end class
|
} // end class
|
||||||
|
|
||||||
function mb (val,p=2) {
|
|
||||||
// console.log(val,val / 1024 / 1024, _.round(val / 1024 / 1024, -p) )
|
|
||||||
return _.round(val / 1024 / 1024, -p)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Memory
|
export default Memory
|
||||||
export { Memory }
|
export { Memory }
|
||||||
|
|
Loading…
Reference in New Issue