agent/eni/watcher/watcher_linux.go
func (udevWatcher *UdevWatcher) sendENIStateChange(mac string) error {
	if mac == "" {
		return errors.New("udev watcher send ENI state change: empty mac address")
	}
	// check if this is an eni required by a task
	eni, ok := udevWatcher.agentState.ENIByMac(mac)
	if !ok {
		return &unmanagedENIError{mac}
	}
	if eni.IsSent() {
		return errors.Errorf("udev watcher send ENI state change: eni status already sent: %s", eni.String())
	}
	if eni.HasExpired() {
		// Agent is aware of the ENI, but we decide not to ack it
		// as it's ack timeout has expired
		udevWatcher.agentState.RemoveENIAttachment(eni.MACAddress)
		return errors.Errorf(
			"udev watcher send ENI state change: eni status expired, no longer tracking it: %s",
			eni.String())
	}

	// We found an ENI, which has the expiration time set in future and
	// needs to be acknowledged as having been 'attached' to the Instance
	go func(eni *apieni.ENIAttachment) {
		eni.Status = apieni.ENIAttached
		log.Infof("Emitting ENI change event for: %s", eni.String())
		udevWatcher.eniChangeEvent <- api.TaskStateChange{
			TaskARN:    eni.TaskARN,
			Attachment: eni,
		}
	}(eni)
	return nil
}
func (udevWatcher *UdevWatcher) sendENIStateChange(mac string) error {
	if mac == "" {
		return errors.New("udev watcher send ENI state change: empty mac address")
	}
	// check if this is an eni required by a task
	eni, ok := udevWatcher.agentState.ENIByMac(mac)
	if !ok {
		return &unmanagedENIError{mac}
	}
	if eni.IsSent() {
		return errors.Errorf("udev watcher send ENI state change: eni status already sent: %s", eni.String())
	}
	if eni.HasExpired() {
		// Agent is aware of the ENI, but we decide not to ack it
		// as it's ack timeout has expired
		udevWatcher.agentState.RemoveENIAttachment(eni.MACAddress)
		return errors.Errorf(
			"udev watcher send ENI state change: eni status expired, no longer tracking it: %s",
			eni.String())
	}

	// We found an ENI, which has the expiration time set in future and
	// needs to be acknowledged as having been 'attached' to the Instance
	go func(eni *apieni.ENIAttachment) {
		eni.Status = apieni.ENIAttached
		log.Infof("Emitting ENI change event for: %s", eni.String())
		udevWatcher.eniChangeEvent <- api.TaskStateChange{
			TaskARN:    eni.TaskARN,
			Attachment: eni,
		}
	}(eni)
	return nil
}
// sendENIStateChange handles the eni event from udev or reconcile phase