obtain a WorkUnit instance based on available memory for the
        worker process.  
        
        :param worker_id: unique identifier string for a worker to
          which a WorkUnit will be assigned, if available.
        :param available_gb: number of gigabytes of RAM available to
          this worker
        :param lease_time: how many seconds to lease a WorkUnit
        :param int max_jobs: maximum number of work units to return (default 1)
        :param work_spec_names: limit to queue from one work_spec. NOT IMPLEMENTD. this implementation will return work from any work spec.

def get_work(self, worker_id, available_gb=None, lease_time=None, work_spec_names=None, max_jobs=None):
        '''obtain a WorkUnit instance based on available memory for the
        worker process.  
        
        :param worker_id: unique identifier string for a worker to
          which a WorkUnit will be assigned, if available.
        :param available_gb: number of gigabytes of RAM available to
          this worker
        :param lease_time: how many seconds to lease a WorkUnit
        :param int max_jobs: maximum number of work units to return (default 1)
        :param work_spec_names: limit to queue from one work_spec. NOT IMPLEMENTD. this implementation will return work from any work spec.

        '''

        if not isinstance(available_gb, (int, float)):
            raise ProgrammerError('must specify available_gb')

        if (max_jobs is not None) and (max_jobs != 1):
            logger.error('redis rejester does not support max_jobs. ignoring and getting 1')

        if lease_time is None:
            lease_time = self.default_lifetime
        work_unit = None

        try: 
            with self.registry.lock(identifier=self.worker_id) as session:
                ## use the simple niceness algorithm described in
                ## http://en.wikipedia.org/wiki/Nice_(Unix)
                ## where each job gets a (20-niceness) share
                nice_levels = session.pull(NICE_LEVELS)
                for work_spec_name, nice in nice_levels.iteritems():
                    nice = min(19, nice)
                    nice = max(-19, nice)
                    nice = 20 - nice
                    nice_levels[work_spec_name] = nice

                while nice_levels:
                    total_nice = sum(nice_levels.values())
                    score = random.randrange(total_nice)
                    work_spec_name = None
                    total_score = 0
                    for wsn, nice in nice_levels.iteritems():
                        total_score += nice
                        if total_score > score:
                            work_spec_name = wsn
                            break
                    assert work_spec_name is not None
                    nice_levels.pop(work_spec_name)
                    
                    ## verify sufficient memory
                    work_spec = session.get(WORK_SPECS, work_spec_name)
                    if available_gb < work_spec['min_gb']:
                        if self.enough_memory:
                            logger.info('Not enough memory to run work '
                                        'spec %s (need %.1f GiB, have '
                                        '%.1f GiB) but running anyways',
                                        work_spec_name,
                                        work_spec['min_gb'],
                                        available_gb)
                        else:
                            logger.info('Not enough memory to run work '
                                        'spec %s (need %.1f GiB, have '
                                        '%.1f GiB)',
                                        work_spec_name,
                                        work_spec['min_gb'],
                                        available_gb)
                            continue

                    ## try to get a task
                    wu_expires = time.time() + lease_time
                    _work_unit = session.getitem_reset(
                        WORK_UNITS_ + work_spec_name,
                        priority_max=time.time(),
                        new_priority=wu_expires,
                        lock=worker_id,
                    )

                    if _work_unit:
                        logger.info('work unit %r', _work_unit)
                        work_unit = WorkUnit(
                            self.registry, work_spec_name,
                            _work_unit[0], _work_unit[1],
                            worker_id=worker_id,
                            expires=wu_expires,
                            default_lifetime=self.default_lifetime,
                        )
                        break

        except (LockError, EnvironmentError):
            logger.error('took to long to get work', exc_info=True)

        logger.debug('get_work %r', work_unit)
        return work_unit