Global variables shared across all requests in Pyramid

1k views Asked by At

I have this code in Pylons that calculates the network usage of the Linux system on which the webapp runs. Basically, to calculate the network utilization, we need to read the file /proc/net/dev twice, which gives us the the amount of transmitted data, and divide the subtracted values by the time elapsed between two reads.

I don’t want to do this calculation at regular intervals. There’s a JS code which periodically fetches this data. The transfer rate is the average amount of transmitted bytes between two requests per time unit. In Pylons, I used pylons.app_globals to store the reading which is going to be subtracted from the next reading at subsequent request. But apparently there’s no app_globals in Pyramid and I’m not sure if using thread locals is the correct course of action. Also, although request.registry.settings is apparently shared across all requests, I’m reluctant to store my data there, as the name implies it should only store the settings.

def netUsage():
    netusage = {'rx':0, 'tx':0, 'time': time.time()}
    rtn = {}
    net_file = open('/proc/net/dev')
    for line in net_file.readlines()[2:]:
        tmp = map(string.atof, re.compile('\d+').findall(line[line.find(':'):]))
        if line[:line.find(':')].strip() == "lo":
            continue
        netusage['rx'] += tmp[0]
        netusage['tx'] += tmp[8]
    net_file.close()
    rx = netusage['rx'] - app_globals.prevNetusage['rx'] if app_globals.prevNetusage['rx'] else 0
    tx = netusage['tx'] - app_globals.prevNetusage['tx'] if app_globals.prevNetusage'tx'] else 0
    elapsed = netusage['time'] - app_globals.prevNetusage['time']
    rtn['rx'] = humanReadable(rx / elapsed)
    rtn['tx'] = humanReadable(tx / elapsed)

    app_globals.prevNetusage = netusage
    return rtn

@memorize(duration = 3)
def getSysStat():
    memTotal, memUsed = getMemUsage()
    net = netUsage()
    loadavg = getLoadAverage()
    return {'cpu': getCPUUsage(),
            'mem': int((memUsed / memTotal) * 100),
            'load1': loadavg[0],
            'load5': loadavg[1],
            'load15': loadavg[2],
            'procNum': loadavg[3],
            'lastProc': loadavg[4],
            'rx': net['rx'],
            'tx': net['tx']
            }
1

There are 1 answers

1
matino On

Using request thread locals is considered bad design and should not be abused according to official pyramid docs.

My advice is to use some simple key-value storage like memcached or redis if possible.