예제 #1
0
        void MarkProblemDevice(ITargetDevice Device)
        {
            if (ProblemDevices.Where(D => D.Name == Device.Name && D.Platform == Device.Platform).Count() > 0)
            {
                return;
            }

            // @todo Notify service of problem (reboot device, notify email, etc)
            // also, pass problem devices to service when asking for reservation, so don't get that device back
            ProblemDevices.Add(new ProblemDevice(Device.Name, Device.Platform));
        }
예제 #2
0
        void MarkProblemDevice(ITargetDevice Device)
        {
            if (ProblemDevices.Where(D => D.Name == Device.Name && D.Platform == Device.Platform).Count() > 0)
            {
                return;
            }

            // report device has a problem to the pool
            DevicePool.Instance.ReportDeviceError(Device, "MarkProblemDevice");

            ProblemDevices.Add(new ProblemDevice(Device.Name, Device.Platform));
        }
예제 #3
0
        /// <summary>
        /// Helper that reserves and returns a list of available devices based on the passed in roles
        /// </summary>
        /// <param name="Configs"></param>
        /// <returns></returns>
        public bool TryReserveDevices()
        {
            List <ITargetDevice> AcquiredDevices = new List <ITargetDevice>();
            List <ITargetDevice> SkippedDevices  = new List <ITargetDevice>();

            ReleaseDevices();

            // figure out how many of each device we need
            Dictionary <UnrealTargetConstraint, int> RequiredDeviceTypes = new Dictionary <UnrealTargetConstraint, int>();
            IEnumerable <UnrealSessionRole>          RolesNeedingDevices = SessionRoles.Where(R => !R.IsNullRole());

            // Get a count of the number of devices required for each platform
            RolesNeedingDevices.ToList().ForEach(C =>
            {
                if (!RequiredDeviceTypes.ContainsKey(C.Constraint))
                {
                    RequiredDeviceTypes[C.Constraint] = 0;
                }
                RequiredDeviceTypes[C.Constraint]++;
            });

            // check whether pool can accommodate devices
            if (!DevicePool.Instance.CheckAvailableDevices(RequiredDeviceTypes, ProblemDevices))
            {
                return(false);
            }

            // AG - this needs more thought as it can either be good (lots of devices under contention, temp failure) or
            // just burn cycles spinning on something that won't ever work...

            // If we had problem devices last time see if there are enough of that type that we can exclude them
            //if (ProblemDevices.Count > 0)
            //{
            //	Dictionary<UnrealTargetPlatform, int> ProblemPlatforms = new Dictionary<UnrealTargetPlatform, int>();

            //	// count how many problems for each platform
            //	ProblemDevices.ForEach(Device =>
            //	{
            //		if (ProblemPlatforms.ContainsKey(Device.Platform) == false)
            //		{
            //			ProblemPlatforms[Device.Platform] = 0;
            //		}

            //		ProblemPlatforms[Device.Platform]++;
            //	});

            //	List<ITargetDevice> ProblemsDevicesToRelease = new List<ITargetDevice>();

            //	// foreach device, see if we have enough others that we can ignore it
            //	ProblemDevices.ForEach(Device =>
            //	{
            //		if (ProblemPlatforms[Device.Platform] < AvailableDeviceTypes[Device.Platform])
            //		{
            //			Log.Verbose("Had problem with device {0} last time, will now ignore", Device.Name);
            //		}
            //		else
            //		{
            //			Log.Verbose("Would like to ignore device {0} but not enough of this type in pool", Device.Name);
            //			ProblemsDevicesToRelease.Add(Device);
            //		}
            //	});

            //	// remove any
            //	ProblemDevices = ProblemDevices.Where(D => ProblemsDevicesToRelease.Contains(D) == false).ToList();
            //}

            // nothing acquired yet...
            AcquiredDevices.Clear();

            // for each platform, enumerate and select from the available devices
            foreach (var PlatformReqKP in RequiredDeviceTypes)
            {
                UnrealTargetConstraint Constraint = PlatformReqKP.Key;
                UnrealTargetPlatform?  Platform   = Constraint.Platform;

                int NeedOfThisType = RequiredDeviceTypes[Constraint];

                DevicePool.Instance.EnumerateDevices(Constraint, Device =>
                {
                    int HaveOfThisType = AcquiredDevices.Where(D => D.Platform == Device.Platform && Constraint.Check(Device)).Count();

                    bool WeWant = NeedOfThisType > HaveOfThisType;


                    if (WeWant)
                    {
                        bool Available = Device.IsAvailable;
                        bool Have      = AcquiredDevices.Contains(Device);

                        bool Problem = ProblemDevices.Where(D => D.Name == Device.Name && D.Platform == Device.Platform).Count() > 0;

                        Log.Verbose("Device {0}: Available:{1}, Have:{2}, HasProblem:{3}", Device.Name, Available, Have, Problem);

                        if (Available &&
                            Have == false &&
                            Problem == false)
                        {
                            Log.Info("Acquiring device {0}", Device.Name);
                            AcquiredDevices.Add(Device);
                            HaveOfThisType++;
                        }
                        else
                        {
                            Log.Info("Skipping device {0}", Device.Name);
                            SkippedDevices.Add(Device);
                        }
                    }

                    // continue if we need more of this platform type
                    return(HaveOfThisType < NeedOfThisType);
                });
            }

            // If we got enough devices, go to step2 where we provision and try to connect them
            if (AcquiredDevices.Count == RolesNeedingDevices.Count())
            {
                // actually acquire them
                DevicePool.Instance.ReserveDevices(AcquiredDevices);

                Log.Info("Selected devices {0} for client(s). Prepping", string.Join(", ", AcquiredDevices));

                foreach (ITargetDevice Device in AcquiredDevices)
                {
                    if (Device.IsOn == false)
                    {
                        Log.Info("Powering on {0}", Device);
                        Device.PowerOn();
                    }
                    else if (Globals.Params.ParseParam("reboot"))
                    {
                        Log.Info("Rebooting {0}", Device);
                        Device.Reboot();
                    }

                    if (Device.IsConnected == false)
                    {
                        Log.Verbose("Connecting to {0}", Device);
                        Device.Connect();
                    }
                }

                // Step 3: Verify we actually connected to them
                var LostDevices = AcquiredDevices.Where(D => !D.IsConnected);

                if (LostDevices.Count() > 0)
                {
                    Log.Info("Lost connection to devices {0} for client(s). ", string.Join(", ", LostDevices));

                    // mark these as problems. Could be something grabbed them before us, could be that they are
                    // unresponsive in some way
                    LostDevices.ToList().ForEach(D => MarkProblemDevice(D));
                    AcquiredDevices.ToList().ForEach(D => D.Disconnect());

                    DevicePool.Instance.ReleaseDevices(AcquiredDevices);
                    AcquiredDevices.Clear();
                }
            }

            if (AcquiredDevices.Count() != RolesNeedingDevices.Count())
            {
                Log.Info("Failed to resolve all devices. Releasing the ones we have ");
                DevicePool.Instance.ReleaseDevices(AcquiredDevices);
            }
            else
            {
                ReservedDevices = AcquiredDevices;
            }

            // release devices that were skipped
            DevicePool.Instance.ReleaseDevices(SkippedDevices);

            return(ReservedDevices.Count() == RolesNeedingDevices.Count());
        }