can-connect
can-connect copied to clipboard
make it easy to log what's happening in can-connect
trafficstars
I'd like to make a little utility to log what's happening in can-connect. I'm working on this now in an effort to debug bitballs.
Posting relevant code:
var connect = require("can-connect");
var WeakReferenceMap = require("can-connect/helpers/weak-reference-map");
var WeakReferenceSet = require("can-connect/helpers/weak-reference-set");
var sortedSetJSON = require("can-connect/helpers/sorted-set-json");
var eventQueue = require("can-event-queue/map/map");
// shared across all connections
var pendingRequests = 0;
var noRequestsTimer = null;
var requests = {
increment: function(connection){
pendingRequests++;
clearTimeout(noRequestsTimer);
},
decrement: function(connection){
pendingRequests--;
if(pendingRequests === 0) {
// this calls to the connection so that `notifyThereAreNoPendingRequests` can be trapped
noRequestsTimer = setTimeout(connection.notifyThereAreNoPendingRequests,module.exports.requestCleanupDelay);
}
if(pendingRequests < 0) {
pendingRequests = 0;
}
},
count: function(){
return pendingRequests;
},
notifyThereAreNoPendingRequests: function(){
requests.dispatch("end");
}
};
eventQueue(requests);
var constructorStore = connect.behavior("constructor/store",function(baseConnection){
var behavior = {
// do this so this method can be logged
notifyThereAreNoPendingRequests: function(){
requests.notifyThereAreNoPendingRequests();
},
This is the log function. It nests stack calls. Traps repeat calls over time.
function logCalls(obj, indent){
console.log( (indent||"") +obj.title+"\n" );
obj.children.forEach(function(child){
logCalls(child,(indent||"")+" ");
});
}
var lasts = [];
var logStack = [];
function logger(obj, root) {
if(!root) {
root = obj;
}
Object.keys(obj).forEach(function(key){
if(obj.hasOwnProperty(key)) {
if(typeof obj[key] === "function" && !canReflect.isConstructorLike(obj[key])) {
var old = obj[key]
obj[key] = function(){
var log = {
title: ""+root.name+" connection."+key+" ("+obj.__behaviorName+")",
meta: {name: key, behavior: obj, fn: old, arguments: arguments, this: this},
children: [],
get clickMeToLogMore(){
logCalls(this,"")
return "stack logged down below";
}
};
if(logStack.length) {
logStack[logStack.length-1].children.push(log);
}
logStack.push(log);
var result = old.apply(this, arguments);
var last = logStack.pop();
if(logStack.length === 0) {
if(lasts.length === 0) {
setTimeout(function(){
var lastsClone = lasts.slice(0);
lasts = [];
lastsClone.forEach(function(last){
console.log(last)
});
},10);
}
if(lasts.length) {
var lastLast = lasts[lasts.length - 1];
if(lastLast.title === last.title) {
if(lastLast.type === "repeat") {
lastLast.children.push(last);
} else {
lasts[lasts.length - 1] = {
title: last.title,
type: "repeat",
children: [lastLast, last]
}
}
} else {
lasts.push(last);
}
} else {
lasts.push(last);
}
}
return result;
}
}
}
})
var proto = Object.getPrototypeOf(obj);
if(proto && proto.__behaviorName) {
logger(proto, root)
}
}
logger(Player.connection);