def iter_cranks(path):
    'split each slogfile into runs (each beginning with an import-kernel event),\n    process each run by finding sequential matching deliver+deliver-result pairs,\n    turn each pair into a (crankNum, computrons, wallclock) triple\n    '
    log.info('iter_cranks: %s', path)
    with gzip.open(path) as f:
        kernel = None
        deliver = None
        block = None
        syscalls = None
        for (ix, line) in enumerate(f):
            try:
                data = json.loads(line)
            except json.JSONDecodeError:
                log.warning('%s:%d: bad JSON: %s', path.name, ix, repr(line))
                continue
            ty = data['type']
            if (ty == 'import-kernel-finish'):
                kernel = data
                deliver = None
                syscalls = None
                (yield dict(kernel, slogfile=path.name, line=ix))
            elif (ty == 'create-vat'):
                (yield dict(slogfile=path.name, line=ix, time=data['time'], type=ty, vatID=data['vatID'], description=data['description'], managerType=data['managerType'], time_kernel=kernel['time']))
            elif (ty == 'cosmic-swingset-end-block-start'):
                block = data
            elif (ty == 'cosmic-swingset-end-block-finish'):
                time = data['time']
                time_start = block['time']
                dur = (time - time_start)
                if kernel:
                    time_kernel = kernel['time']
                else:
                    log.warning('%s:%d: missing kernel context', path.name, ix)
                    time_kernel = np.nan
                (yield dict(slogfile=path.name, line=ix, time=time, type=ty, time_start=time_start, dur=dur, blockHeight=data['blockHeight'], blockTime=data['blockTime'], time_kernel=time_kernel))
                block = None
            elif (deliver is None):
                if (ty == 'deliver'):
                    deliver = data
                    syscalls = 0
            elif (data['type'] == 'deliver-result'):
                time = data['time']
                time_start = deliver['time']
                dur = (time - time_start)
                method = (deliver['kd'][2]['method'] if (deliver['kd'][0] == 'message') else None)
                compute = (data['dr'][2]['compute'] if (type(data['dr'][2]) is type({})) else None)
                if block:
                    blockHeight = block['blockHeight']
                    blockTime = block['blockTime']
                else:
                    log.warning('%s:%d: missing block context', path.name, ix)
                    blockHeight = blockTime = np.nan
                if kernel:
                    time_kernel = kernel['time']
                else:
                    log.warning('%s:%d: missing kernel context', path.name, ix)
                    time_kernel = np.nan
                (yield dict(slogfile=path.name, line=ix, time=time, type=ty, crankNum=data['crankNum'], deliveryNum=data['deliveryNum'], vatID=data['vatID'], kd=deliver['kd'], method=method, syscalls=syscalls, dr=data['dr'], compute=compute, time_start=time_start, dur=dur, blockHeight=blockHeight, blockTime=blockTime, time_kernel=time_kernel))
                deliver = None
            elif (ty == 'syscall-result'):
                syscalls += 1
            elif (ty in ['clist', 'syscall']):
                continue
            else:
                log.warning('%s:%d: expected deliver-result; got: %s', path.name, ix, ty)
                deliver = None
split each slogfile into runs (each beginning with an import-kernel event),
process each run by finding sequential matching deliver+deliver-result pairs,
turn each pair into a (crankNum, computrons, wallclock) triple
def iter_cranks(path):
    'split each slogfile into runs (each beginning with an import-kernel event),\n    process each run by finding sequential matching deliver+deliver-result pairs,\n    turn each pair into a (crankNum, computrons, wallclock) triple\n    '
    log.info('iter_cranks: %s', path)
    with gzip.open(path) as f:
        kernel = None
        deliver = None
        block = None
        syscalls = None
        for (ix, line) in enumerate(f):
            try:
                data = json.loads(line)
            except json.JSONDecodeError:
                log.warning('%s:%d: bad JSON: %s', path.name, ix, repr(line))
                continue
            ty = data['type']
            if (ty == 'import-kernel-finish'):
                kernel = data
                deliver = None
                syscalls = None
                (yield dict(kernel, slogfile=path.name, line=ix))
            elif (ty == 'create-vat'):
                (yield dict(slogfile=path.name, line=ix, time=data['time'], type=ty, vatID=data['vatID'], description=data['description'], managerType=data['managerType'], time_kernel=kernel['time']))
            elif (ty == 'cosmic-swingset-end-block-start'):
                block = data
            elif (ty == 'cosmic-swingset-end-block-finish'):
                time = data['time']
                time_start = block['time']
                dur = (time - time_start)
                if kernel:
                    time_kernel = kernel['time']
                else:
                    log.warning('%s:%d: missing kernel context', path.name, ix)
                    time_kernel = np.nan
                (yield dict(slogfile=path.name, line=ix, time=time, type=ty, time_start=time_start, dur=dur, blockHeight=data['blockHeight'], blockTime=data['blockTime'], time_kernel=time_kernel))
                block = None
            elif (deliver is None):
                if (ty == 'deliver'):
                    deliver = data
                    syscalls = 0
            elif (data['type'] == 'deliver-result'):
                time = data['time']
                time_start = deliver['time']
                dur = (time - time_start)
                method = (deliver['kd'][2]['method'] if (deliver['kd'][0] == 'message') else None)
                compute = (data['dr'][2]['compute'] if (type(data['dr'][2]) is type({})) else None)
                if block:
                    blockHeight = block['blockHeight']
                    blockTime = block['blockTime']
                else:
                    log.warning('%s:%d: missing block context', path.name, ix)
                    blockHeight = blockTime = np.nan
                if kernel:
                    time_kernel = kernel['time']
                else:
                    log.warning('%s:%d: missing kernel context', path.name, ix)
                    time_kernel = np.nan
                (yield dict(slogfile=path.name, line=ix, time=time, type=ty, crankNum=data['crankNum'], deliveryNum=data['deliveryNum'], vatID=data['vatID'], kd=deliver['kd'], method=method, syscalls=syscalls, dr=data['dr'], compute=compute, time_start=time_start, dur=dur, blockHeight=blockHeight, blockTime=blockTime, time_kernel=time_kernel))
                deliver = None
            elif (ty == 'syscall-result'):
                syscalls += 1
            elif (ty in ['clist', 'syscall']):
                continue
            else:
                log.warning('%s:%d: expected deliver-result; got: %s', path.name, ix, ty)
                deliver = None