You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: try_on_host.go
    path of file: ./repos/heketi/apps/glusterfs
    
    the code of the file until where you have to start completion: //
// Copyright (c) 2018 The heketi Authors
//
// This file is licensed to you under your choice of the GNU Lesser
// General Public License, version 3 or any later version (LGPLv3 or
// later), or the GNU General Public License, version 2 (GPLv2), in all
// cases as published by the Free Software Foundation.
//

package glusterfs

import (
	"fmt"
)

// nodeHosts is a mapping from the node ID to the hosts's
// management name.
type nodeHosts map[string]string

type tryOnHosts struct {
	Hosts nodeHosts
	done  func(error) bool
	// nodesUp allows ht user of try on hosts to override the default
	// function for fetching
	nodesUp func() map[string]bool
}

func newTryOnHosts(hosts nodeHosts) *tryOnHosts {
	return &tryOnHosts{Hosts: hosts}
}

// nodeStatus return a map of all the known node status
// with a true value indicating the node is 
    
func (c *tryOnHosts) run(f func(host string) error) error {
	// if a custom done is not provided only stop
	// if err == nil
	done := c.done
	if done == nil {
		done = func(err error) bool {
			return err == nil
		}
	}

	mherr := HostErrorMap{}
	tries := 0
	nodeUp := c.nodeStatus()
	for nodeId, host := range c.Hosts {
		if up, found := nodeUp[nodeId]; found && !up {
			// if the node is in the cache and we know it was not
			// recently healthy, skip it
			logger.Debug("skipping node. %v (%v) is presumed unhealthy",
				nodeId, host)
			continue
		}
		logger.Debug("running function on node %v (%v)", nodeId, host)
		tries++
		err := f(host)
		logger.Debug("running function on node %v got: %v", nodeId, err)
		if done(err) {
			return err
		}
		mherr.Add(host, err)
		logger.Warning("error running on node %v (%v): %v", nodeId, host, err)
	}
	if tries == 0 {
		return fmt.Errorf("no hosts available (%v total)", len(c.Hosts))
	}
	logger.Warning(
		"all hosts failed (%v total, %v tried)", len(c.Hosts), tries)
	return mherr.ToError("")
}