Создайте лямбда-функцию AWS для отключения экземпляров на основе низкой загрузки ЦП

Возможность размещения переменных экземпляра в блоке @implementation или в расширении класса является функцией «современной среды выполнения Objective-C», которая используется каждой версией iOS и 64-разрядным Mac OS X.

Если вы хотите писать 32-разрядные приложения Mac OS X, вы должны поместить свои переменные экземпляра в объявление @interface. Скорее всего, вам не нужно поддерживать 32-разрядную версию вашего приложения. OS X поддерживает 64-разрядные приложения с версии 10.5 (Leopard), которая была выпущена более пяти лет назад.

Итак, предположим, вы только пишете приложения, которые будут использовать современную среду исполнения.

Вариант 0: В @interface (Do not Do It)

Сначала давайте рассмотрим, почему мы не имеем хотите поместить переменные экземпляра в объявление @interface.

  1. Ввод переменных экземпляра в @interface предоставляет детали реализации для пользователей класса. Это может привести к тому, что пользователи (даже сами, используя собственные классы!) Будут полагаться на детали реализации, которых они не должны. (Это не зависит от того, объявляем ли мы ivars @private.)
  2. Помещение переменных экземпляра в @interface делает компиляцию более продолжительной, потому что, когда мы добавляем, изменяем или удаляем декларацию ivar, мы необходимо перекомпилировать каждый файл .m, который импортирует интерфейс.

Поэтому мы не хотим помещать переменные экземпляра в @interface.

Вариант 2: В @implementation без брекетов (Do not Do It)

Далее, давайте обсудим ваш вариант 2: «Положите iVars под @ воплощение без блока фигурных скобок ». Это не объявляет переменные экземпляра! Вы говорите об этом:

@implementation Person

int age;
NSString *name;

...

Этот код определяет две глобальные переменные. Он не объявляет никаких переменных экземпляра.

Хорошо определить глобальные переменные в вашем .m файле, даже в вашем @implementation, если вам нужны глобальные переменные - например, потому что вы хотите, чтобы все ваши экземпляры для совместного доступа к определенному состоянию, например кэш. Но вы не можете использовать эту опцию для объявления ivars, потому что она не объявляет ivars. (Кроме того, глобальные переменные, частные для вашей реализации, обычно должны быть объявлены static, чтобы избежать загрязнения глобального пространства имен и риска ошибок времени ссылки.)

Это оставляет ваши варианты 1 и 3.

Вариант 1: В @implementation с фигурными скобками (Do It)

Обычно мы хотим использовать опцию 1: поместите их в ваш основной блок @implementation в фигурных скобках, например:

@implementation Person {
    int age;
    NSString *name;
}

Мы помещаем их здесь, потому что они сохраняют свое существование частным образом, предотвращая проблемы, описанные мной ранее, и потому, что обычно нет причин помещать их в расширение класса.

Итак, когда мы хотите использовать свой вариант 3, помещая их в расширение класса?

Вариант 3: в расширении класса (делать это только при необходимости)

Практически никогда не бывает причин для их использования в расширении класса в том же файле, что и класс @implementation класса. Мы могли бы просто поместить их в @implementation в этом случае.

Но иногда мы могли бы написать класс, который достаточно велик, и мы хотим разделить его исходный код на несколько файлов. Мы можем сделать это с помощью категорий. Например, если бы мы реализовали UICollectionView (довольно большой класс), мы могли бы решить, что мы хотим поместить код, который управляет очередями многоразовых представлений (ячеек и дополнительных представлений) в отдельном исходном файле. Мы могли бы это сделать, разделив эти сообщения на категорию:

// UICollectionView.h

@interface UICollectionView : UIScrollView

- (id)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout;
@property (nonatomic, retain) UICollectionView *collectionViewLayout;
// etc.

@end

@interface UICollectionView (ReusableViews)

- (void)registerClass:(Class)cellClass forCellWithReuseIdentifier:(NSString *)identifier;
- (void)registerNib:(UINib *)nib forCellWithReuseIdentifier:(NSString *)identifier;

- (void)registerClass:(Class)viewClass forSupplementaryViewOfKind:(NSString *)elementKind withReuseIdentifier:(NSString *)identifier;
- (void)registerNib:(UINib *)nib forSupplementaryViewOfKind:(NSString *)kind withReuseIdentifier:(NSString *)identifier;

- (id)dequeueReusableCellWithReuseIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath*)indexPath;
- (id)dequeueReusableSupplementaryViewOfKind:(NSString*)elementKind withReuseIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath*)indexPath;

@end

OK, теперь мы можем реализовать основные UICollectionView методы в UICollectionView.m, и мы можем реализовать методы, которые управляют многоразовыми представлениями в UICollectionView+ReusableViews.m, что делает наш исходный код немного более управляемым.

Но нашему многоразовому коду управления представлением нужны некоторые переменные экземпляра. Эти переменные должны быть подвержены основному классу @implementation в UICollectionView.m, поэтому компилятор испустит их в файле .o. И нам также нужно подвергнуть эти переменные экземпляра коду в UICollectionView+ReusableViews.m, поэтому эти методы могут использовать ivars.

Здесь нам нужно расширение класса. Мы можем добавить ivars для многоразового просмотра в расширение класса в закрытом файле заголовка:

// UICollectionView_ReusableViewsSupport.h

@interface UICollectionView () {
    NSMutableDictionary *registeredCellSources;
    NSMutableDictionary *spareCellsByIdentifier;

    NSMutableDictionary *registeredSupplementaryViewSources;
    NSMutableDictionary *spareSupplementaryViewsByIdentifier;
}

- (void)initReusableViewSupport;

@end

Мы не будем отправлять этот заголовочный файл пользователям нашей библиотеки. Мы просто импортируем его в UICollectionView.m и в UICollectionView+ReusableViews.m, чтобы все, что нуждалось в , чтобы увидеть эти ивары, могут их видеть. Мы также выбрали метод, который мы хотим, чтобы основной метод init вызывал инициализацию кода управления повторного просмотра. Мы будем называть этот метод из -[UICollectionView initWithFrame:collectionViewLayout:] в UICollectionView.m, и мы его реализуем в UICollectionView+ReusableViews.m.

1
задан bwest 26 February 2019 в 20:08
поделиться

1 ответ

Похоже, что вы должны проверять все экземпляры Amazon EC2 в данном VPC каждые n минут на предмет низкой загрузки ЦП. Если оно падает ниже заданного порога, такие случаи должны быть остановлены.

Во-первых, обратите внимание, что загрузка ЦП может не быть хорошей мерой «использования». Вы упоминаете студентов, которые предполагают, что может быть много интерактивной командной строки, которая не использует много ЦП. Вам нужно будет поэкспериментировать, чтобы найти хороший «триггер», который указывает на неиспользование.

Вместо создания отдельных аварийных сигналов Amazon CloudWatch я бы порекомендовал:

  • Создать правило Amazon CloudWatch Events , которое запускает функцию AWS Lambda каждые n минут
  • Лямбда-функция будет:
    • Вызвать DescribeInstances() - , получить список экземпляров EC2 (либо выполнить фильтрацию до VPC в вызове API, либо выполнить фильтрацию после ответ получен)
    • Для каждого экземпляра, если экземпляр выполняется, получить использование ЦП CloudWatch Metrics для экземпляра (который по умолчанию регистрируется каждые 5 минут) в течение требуемого периода времени (например, в течение последних 15 минут)
    • Если экземпляр находится ниже желаемого порога, вызовите EC2 - Остановите экземпляр

Этот метод автоматически обрабатывает любой экземпляр в VPC без необходимости создавать / удалять аварийные сигналы, характерные для каждого экземпляра.

0
ответ дан John Rotenstein 26 February 2019 в 20:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: