Translate

вторник, 9 декабря 2014 г.

Немного о runas

Так уж сложилось, что в текущем месте работы приходится жить в двух доменах.

ПК работает в одном, а учетная запись под которой доступ к ресурсам в другом.

Простой способ обойти проблемы с этим связанные - использование runas:
runas.exe /netonly /user:<user>@<domain> "<app cmd>"

Конечно, при каждом запуске программы требуется вводить пароль от домена клиента, но все работает более или менее корректно.

четверг, 13 ноября 2014 г.

Visual Studio стала бесплатной теперь в версии Pro.

Я, конечно, понимаю, что та стоимость, которая была у VS Pro не значительна, и, даже, доступна вместе с TFS online, но все таки наличие бесплатной Community версии стало приятной неожиданностью.

Собственно ссылка:
http://www.visualstudio.com/products/visual-studio-community-vs

Правда в ближайшее время пробовать ее вряд ли буду. На обоих ноутбуках плотно живет VS 2013 Ultimate. Смысла что-то менять пока не вижу.

В настоящее время направление деятельности малость поменялось. Вновь есть о чем писать. Ждите новостей.

пятница, 24 октября 2014 г.

Системы построения корпоративной отчетности. Немного мыслей.

Давно я не писал в данный блог. Это не значит, что я не занимался разработкой ПО. Просто не до этого было... Да и не интересно писать про стандартные вещи или legacy технологии, которыми по прозе жизни иногда приходится долгое время заниматься.

Так уж сложились звезды, что одной из задач, которую пришлось решать стало построение сводной отчетности по нескольким системам.

Обычно при всей сложности данных систем - значимой технической сложности в них обычно нет. Задачи из области Big Data решаются коробочными продуктами (на же надо результат получить и быстро, а не новый тип софта писать).

Попытки сделать это "на коленках" работают ровно до появления большого количества цифр. Далее процесс плавно уходит в область длительных пересчетов или сложной модернизации и проект плавно становится тяжело обслуживаемым.

В случае выбора готовых решений для постоения систем есть несколько подводных камней:
1) Правильное понимание горизонта задачи
Как правило, бизнес-пользователь понимает задачу как "соберите мне 2-3 значения. это же так просто" или еще проще "сделайте мне график", что автоматически ведет началу выбора системы визуализации данных.
Это правильный шаг, но часто на нем решение и ограничивается. Любой пакет визуализации данных содержим необходимый минимум ETL функционала. Как правило это умение читать несколько источников, простые склейки таблиц и т.д.
Ошибкой является остановка выбора только на данном шаге. В круг задач этих систем входит прежде всего быстрая визуализация данных, но никак не их сбор и агрегация.
Для многих аналитических отчетов необходимо хранение архивных данных, возможность подключения к различным источникам по различным протоколам, включая web-сервисы, авторизацию Active Directory, и выполнение части преобразования данных в нереляционных терминах (исполняемым кодом). В этих вещах такие системы пасуют или решают задачу неэффективно. Для этих вопросов существуют системы построения Data Warehouse, которые внутри себя решают эти проблемы и выдают наверх универсальные срезы, решая задачи сбора и хранения данных с требуемой частотой.

2) Стоимость лицензирования
Стоимость приобретения систем зависит от многих факторов:
-количества данных, планируемых к обработке и хранению
-имеющихся лицензий на другие продукты
-количества пользователей, которым нужен доступ к системе
и т.д.

Практически все системы предоставляют бесплатный или недорогой вариант для построения систем начального уровня. Это позволяет быстро начать движение и получить первые результаты без значительных затрат средств. Построение этих систем процесс долгий и требует вовлеченности представителей бизнеса, которым нужен всегда быстрый результат.
Однако категорически неверно выбирать платформу по цене стартового пакета. Зачастую переход с одного пакета на другой может потребовать значительных вложений, причем в большем объеме, чем стартовая стоимость.

3) Требования по оперативности обновления данных
Есть два основных критерия построения систем отчетности:
-быстрота (реальное время) и точность.

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

Данные системы разносят в разный класс приложений. Первые работают на основе систем построенных на принципах map-reduce. И отчеты строятся по всем данным, попадающим в систему с откидыванием неверных данных.

Вторые - на основе реляционных баз данных с надстройками в виде метаданных агрегаций, ускоряющих скорость чтения данных. Обновление таких систем происходит по расписанию и валидируется различными контрольными сообщениями.

5) Визуализация информации
Задача визуализации, как правило, включает в себя решение вопросов доступности на всем диапазоне устройств, защиты доступа к хранилищам для внешних пользователей, централизованного обновления информации.
Этот блок является видимой частью айсберга. Главными критериями его выбора должны быть простота освоения пользователями, удобство настройки и быстрота отображения данных (первичных и доп. запросов).

вторник, 11 сентября 2012 г.

Dynamic OrderBy в Linq

Частая задача при работе с наборами данных Linq - сортировка по полю заданному из строкового параметра (например GridView onSorting).

Конечно, можно сделать простую конструкцию типа case:

switch(param) {
case 'Field1':  return table.OrderBy(t=>t.Field1);
case 'Field2':  return table.OrderBy(t=>t.Field2);
case 'Field3':  return table.OrderBy(t=>t.Field3);
}

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

На помощь пришла статья с stackoverflow: http://stackoverflow.com/questions/41244/dynamic-linq-orderby

Далее краткий snippet кода:

public static class DynamicSortHelper
    {
        public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source, string property)
        {
            return ApplyOrder<T>(source, property, "OrderBy");
        }
        public static IOrderedQueryable<T> OrderByDescending<T>(this IQueryable<T> source, string property)
        {
            return ApplyOrder<T>(source, property, "OrderByDescending");
        }
        public static IOrderedQueryable<T> ThenBy<T>(this IOrderedQueryable<T> source, string property)
        {
            return ApplyOrder<T>(source, property, "ThenBy");
        }
        public static IOrderedQueryable<T> ThenByDescending<T>(this IOrderedQueryable<T> source, string property)
        {
            return ApplyOrder<T>(source, property, "ThenByDescending");
        }
        static IOrderedQueryable<T> ApplyOrder<T>(IQueryable<T> source, string property, string methodName)
        {
            string[] props = property.Split('.');
            Type type = typeof(T);
            ParameterExpression arg = Expression.Parameter(type, "x");
            Expression expr = arg;
            foreach (string prop in props)
            {
                // use reflection (not ComponentModel) to mirror LINQ
                PropertyInfo pi = type.GetProperty(prop);
                expr = Expression.Property(expr, pi);
                type = pi.PropertyType;
            }
            Type delegateType = typeof(Func<,>).MakeGenericType(typeof(T), type);
            LambdaExpression lambda = Expression.Lambda(delegateType, expr, arg);

            object result = typeof(Queryable).GetMethods().Single(
                    method => method.Name == methodName
                            && method.IsGenericMethodDefinition
                            && method.GetGenericArguments().Length == 2
                            && method.GetParameters().Length == 2)
                    .MakeGenericMethod(typeof(T), type)
                    .Invoke(null, new object[] { source, lambda });
            return (IOrderedQueryable<T>)result;
        }
    }

четверг, 16 августа 2012 г.

Немного о проблеме "Все соединения заняты" в Remote Desktop Connection

Для многих, кто имеет отношения к серверам windows в корпоративном окружении, проблема знакома. Причина - неудобно сделанная процедура окончания сессии. Вместо того, чтобы сделать "Пуск"-"Выход из системы" проще нажать на крестик наверху. Так делают многие и я не исключение.

Что же делать, если ваши коллеги накануне заняли все доступные соединения, а на сервер кровь из носу надо:

Универсальный способ - воспользоваться ключем /admin

В командной строке набираем mstsc.exe /admin (mstsc.exe /console для подключения к Windows 2000 (если у кого он еще живет)). 

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

Далее через вкладку Users в Task Manager можно отключить от сервера забывчивых коллег и войти уже нормальным способом.

вторник, 7 августа 2012 г.

Немного о Warm up

В любом web-приложении наступает этап, когда функциональные требования закрыты, профайлер отложен в сторону, т.к. все уже приемлемо "летает" на dev, код ушел на тестовые окружения, но... при первом запуске все сильно тормозит...

Далее все летает, но первый запуск... Подобная проблема есть в большинстве возможных платформ... Для ряда платформ есть более эффективные методики. Для reverse proxy, например, это использование key-value базы с предпубликованным контентом как источника данных,
Для IIS 7.5 это autostart module или магическая фича autostart ASP.NET 4 (эффект которой я немного не заметил).

Общее решение здесь - запланированная задача, которая вызывает наиболее важные ссылки раз в заданный период и тонкая настройка периодов реинициализиции приложений.

Как это автоматизировать? Просто.

Существуют простые утилиты, такие как curl, которые позволяют из командной строки "дернуть" интересующие ссылки и таким образом инициализировать кэши заново.

Период запуска запланированной задачи сильно зависит от настроек платформы и варьируется от раз в 5 минут, до раз в день.