/** * Finds the first slot that works for the passed index. * * @param integer $nth * The 1-based index of the item in the group. * * @return Slot * The Slot for the passed index. */ public function slotForNth($nth) { $slot = F\first($this->slots, function ($slot) use($nth) { return is_callable($slot[0]) ? $slot[0]($nth) : true; }); return $slot[1]; }
/** * Check if all types are the same, in which case just return that type. * Otherwise, create the UnionType and return. * Also automatically flatten all nested UnionTypes. * * @param Type $type Require at least one type * @param Type|Type[] ...$types * * @return UnionType|Type */ public static function createIfNotDuplicate(Type $type, Type ...$types) { $types = array_merge([$type], $types); // Flatten nested UnionTypes $types = Type::flatten($types); if (array_any($types, function (Type $type, $key, array $collection) { return $type instanceof UnionType; })) { throw new \LogicException("UnionType::flatten() failed to flatten nested UnionTypes."); } $types = Type::unique($types); if (count($types) <= 1) { return first($types); } return new UnionType(array_shift($types), $types); }
public function juggle(Type $type) { /* * This is a predicate to determine whether the CURRENT type (the child class) * can be juggled into the Type $type. */ $predicate = function (Type $element) { return array_any($this->getAllowedJuggleTypes(), function (Type $value, $index, $collection) use($element) { return (bool) Type::intersect($element, $value); }); }; $x = array_filter($type->getTypes(), $predicate); if (!$x) { return null; } if (count($x) === 1) { return first($x); } return UnionType::createIfNotDuplicate(array_shift($x), ...$x); }
/** * Flatten Types, e.g. flatten UnionTypes. * * This function won't have much of an effect on most types, unless they contain subtypes. * * Because this function preserves duplicate entries, usually it may be preferable to use Type::unique() * which also flattens and removes duplicate entries. * * @param Type|Type[] ...$types Use array dereferencing to pass an array into this function. * * @return array */ public static function flatten(Type ...$types) { // Flatten types with subtypes e.g. UnionTypes $walker = function (Type $x) { // If the types $x contains is not just itself, go deeper! if (count($x->getTypes()) !== 1 or !first($x->getTypes())->typeof($x)) { return Type::flatten($x); } return $x->getTypes(); }; $x = array_map($walker, $types); return array_flatten($x); }
public function handle() { $this->info('Initializing Leader Selection...'); // Only do cron setup if environment is configured to use it (This way we don't accidentally run on workers) if (getenv('USE_CRON') == 'true') { //check to see if we are in an instance $ch = curl_init('http://169.254.169.254/latest/meta-data/instance-id'); //magic ip from AWS curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); if ($result = curl_exec($ch)) { $this->info('Instance ID: ' . $result); // Get this instance metadata so we can find the environment it's running in $tags = $info = $this->ecClient->describeInstances(['Filters' => [['Name' => 'instance-id', 'Values' => [$result]]]])->get('Reservations')[0]['Instances'][0]['Tags']; // Get environment name $environmentName = F\first($tags, function ($tagArray) { return $tagArray['Key'] == 'elasticbeanstalk:environment-name'; })['Value']; $this->info('Environment: ' . $environmentName); $this->info('Getting Instances with Environment: ' . $environmentName); // Get instances that have this environment tagged $info = $this->ecClient->describeInstances(['Filters' => [['Name' => 'tag-value', 'Values' => [$environmentName]]]]); $instances = F\map($info->get('Reservations'), function ($i) { return current($i['Instances']); }); $this->info('Getting potential instances...'); // Only want instances that are running $candidateInstances = F\select($instances, function ($instanceMeta) { return $instanceMeta['State']['Code'] == 16; }); $leader = false; if (!empty($candidateInstances)) { //there are instances running if (count($candidateInstances) > 1) { // if there is more than one we sort by launch time and get the oldest $this->info('More than one instance running, finding the oldest...'); $oldestInstance = F\sort($candidateInstances, function ($left, $right) { return $left['LaunchTime'] > $right['LaunchTime']; })[0]; } else { $this->info('Only one instance running...'); $oldestInstance = reset($candidateInstances); } if ($oldestInstance['InstanceId'] == $result) { // if this instance is the oldest instance it's the leader $leader = true; } } else { $this->info('No candidate instances found. \'O Brave New World!'); $leader = true; } // No leader is running so we'll setup this one as the leader // and create a cron entry to run the scheduler if ($leader) { $this->info('We are the Leader! Initiating Cron Setup'); $this->call('system:start:cron'); } else { // Instance was found, don't do any cron stuff $this->info('We are not a leader instance :( Maybe next time...'); $this->info('Leader should be running on Instance ' . $leader['InstanceId']); } $this->info('Leader Selection Done!'); } else { // Probably be run from your local machine $this->error('Did not detect an ec2 environment. Exiting.'); } } else { $this->info('USE_CRON env var not set. Exiting.'); } }
/** * @return mixed */ public function first() { return F\first($this->_data); }