PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Friday, September 30, 2022

[FIXED] Why does a result() from concurrent.futures.as_completed() occasionally return None?

 September 30, 2022     concurrency, concurrent.futures, multithreading, python, python-multithreading     No comments   

Issue

I've been writing a fairly complex series of modules to help test our poorly documented networking gear, this one focused on trying the various passwords used across the company. I've been using the concurrent.futures module to speed things along by testing many devices in parallel but am running in to a problem where occasionally a result comes back as None and it's a mystery to me as why. It revolves around this chunk of code:

def process_device(dev):
    check = CheckPass(creds, inv_list)
    dev = switch.Switch(**dev)
    online, net_device = check.device_online(dev)
    if online == True:
        conn, net_device = check.try_passwords(dev, return_conn=True)
        if conn != False and conn != "none":
            if conn != True:
                hostname,model,serial_num,version,date = net_device.get_id_details(conn)
                net_device.hostname = hostname
                net_device.model = model
                net_device.serial_num = serial_num
                net_device.version = version
                net_device.date = date
                conn.disconnect()
            conf_dev = check.confirm_device(net_device)
            check.dev_confirmed.append(conf_dev)
            return dev.hostname, dev.ip        

with concurrent.futures.ThreadPoolExecutor(max_workers=120) as executor:
    threads = {executor.submit(process_device, dev): dev for dev in inv_list}
    for future in concurrent.futures.as_completed(threads):
        name, ip = future.result()

At unpredictable intervals future.result() will have a result of None and I can't reliably reproduce it. The error occurs with different devices every time, I've checked the logs and fed it an inventory list containing just the device that it had processed and running that device by itself will be fine. I have tried using fewer workers and more. Clearly I'm not understanding something about how future.result() works. dev.hostname and dev.ip always have values so process_device() should always return them (barring unhandled exceptions, which haven't occurred) yet I always end up with TypeError: Cannot unpack non-iterable NoneType object referencing the name, ip = future.results() command.


Solution

It is not problem with future but with your function process_device() which sometimes can return None.

When online is False or when if conn != False and conn != "none": gives False then process_device() will run default return None

def process_device(dev):

    # ... your code ...

    return None  # default behavior

You should filter results

result = future.result()
if result:
    name, ip = result


Answered By - furas
Answer Checked By - Cary Denson (PHPFixing Admin)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing