Начинающим админам SharePoint
Что нужно почитать чтобы правильно развернуть ферму в вашей организации.
Подготовка
https://www.nothingbutsharepoint.com/sites/itpro/Articles/Pages/life-on-the-farm-intro.aspx
https://www.nothingbutsharepoint.com/sites/itpro/Articles/Pages/life-on-the-farm-prep-work-1.aspx
https://www.nothingbutsharepoint.com/sites/itpro/Articles/Pages/life-on-the-farm-prep-work-2.aspx
https://www.nothingbutsharepoint.com/sites/itpro/Articles/Pages/life-on-the-farm-prep-work-3.aspx
https://www.nothingbutsharepoint.com/sites/itpro/Articles/Pages/life-on-the-farm-prep-work-4.aspx
Установка
https://www.nothingbutsharepoint.com/sites/itpro/Articles/Pages/life-on-the-farm-installation.aspx
Настройка
https://www.nothingbutsharepoint.com/sites/itpro/Pages/life-on-the-farm-post-install-configure-part-1.aspx
https://www.nothingbutsharepoint.com/sites/itpro/Articles/Pages/life-on-the-farm-post-install-configure-part-2.aspx
https://www.nothingbutsharepoint.com/sites/itpro/Articles/Pages/life-on-the-farm-post-install-part-3.aspx
https://www.nothingbutsharepoint.com/sites/itpro/Pages/Life-on-the-Farm-SP2010-Configuration---Post-Install-Setup-Part-4.aspx
https://www.nothingbutsharepoint.com/sites/itpro/Articles/Pages/life-on-the-farm-post-install-configure-part-5.aspx
https://www.nothingbutsharepoint.com/sites/itpro/Articles/Pages/life-on-the-farm-post-install-configure-part-6.aspx
https://www.nothingbutsharepoint.com/sites/itpro/Pages/life-on-the-farm-post-install-configure-part-7.aspx
https://www.nothingbutsharepoint.com/sites/itpro/Pages/life-on-the-farm-post-install-configure-part-8.aspx
https://www.nothingbutsharepoint.com/sites/itpro/Pages/life-on-the-farm-post-install-configure-part-9.aspx
https://www.nothingbutsharepoint.com/sites/itpro/Articles/Pages/life-on-the-farm-post-install-configure-part-10.aspx
https://www.nothingbutsharepoint.com/sites/itpro/Pages/life-on-the-farm-post-install-configure-part-11.aspx
Процессинг в SharePoint
SharePoint обладает всеми свойствами распределенной БД. Разные семейства сайтов могут находиться в разных контентных базах данных. Разные контентные БД могут находиться на разных серверах. Запросы к структурированным данным работают небыстро и самый эффективный способ – обращение по ключу. Часто используется поиск для нахождения нужных данных во всей базе.
Для того чтобы обрабатывать много данных в базах SharePoint используются задачи таймера, которые выполняют запросы к БД и обрабатывают полученные данные. Но не для всех случаев запросы можно выполнить эффективно.
Например попробуем спроектировать фичу уведомлений о наступлении некоторой даты. Например предупреждать за несколько дней заинтересованных лиц о наступлении события из календаря с возможностью выбора поля даты, для которого будет приходить уведомление.
Нам обязательно понадобится задача таймера, которая будет бегать по всем спискам всех коллекций сайтов всех баз данных в пределах одного приложения с целью найти нужные элементы для уведомлений. Такой подход отметаем сразу как не масштабируемый.
Другой подход – создавать процесс с ожиданием до заданного времени. Но процессы тяжеловесны и их использование отражается на интерфейсе пользователя. Кроме того есть ограничения на количество работающих процессов в SharePoint. Тоже плохо масштабируется
Нам нужен способ позволяющий передать данные из фронтэнда (веб-приложения) в бекэнд (службу таймера). В распределенных приложениях для этого используются очереди. Но беглый просмотр API шарепоинта говорит нам что очередей нет, а в SharePoint 2010 нельзя из контекста веб-приложения изменить свойства объектов, унаследованных от SPPersitedObject (подробнее тут), и мы не можем записать что-либо в сам объект задачи таймера или в любой дочерний.
Более детальный просмотр Server OM показал одну маленькую функцию SPSite.AddWorkItem, которая добавляет куда-то workitem, и класс SPWorkItemJobDefinition наследуясь от которого можно определить задачу таймера, разгребающую эти workitem. Вот где прятались очереди в sharepoint.
Таким образом мы можем в обработчике события на изменение элемента ставить задачу в очередь, указывая дату и время когда она должна быть обработана, а обо всем остальном позаботятся внутренние механизмы.
Удивляет отсутствие толковой документации и примеров использования этого метода. Похоже что это внутренний механизм, который частично торчит наружу, но далеко не до всех деталей, которые используют процессы и алерты (да-да, они именно такой метод используют) можно добраться. Тем не менее то что доступно вполне можно использовать для своих целей.
Не используйте Thread.Start
Большинство программистов .NET начинают свое знакомство с асинхронностью и параллельностью с метода Thread.Start. Это полезно для понимания внутренних механизмов работы многопоточности, но очень вредно для написания production кода.
Вызов Thread.Start чаще всего используется в двух случаях: когда вам надо запустить длительные вычисления параллельно с основным потоком и когда необходимо выполнить некоторый вызов без блокировки основного потока. Эти задачи похожи между собой но эффективно реализуются различными способами.
Откладывание вызова
Для данной операции можно использовать
- Пул потоков: System.Threading.ThreadPool - не рекомендуется.
- SynchronizationContext и его метод Post
- TPL
Выполнение длительной операции
Тут немного другие варианты будут удобны:
- BackgroundWorker - практически идеальный вариант для GUI так как содержит события для отслеживания хода выполнения.
- TPL при использовании продолжений
Использование ThreadPool для длительных вычислений крайне не рекомендуется, потому что количество потоков в пуле ограничено и создаются они небыстро. Поэтому запуск длительных вычислений в ThreadPool может привести к ухудшению производительности.
Как можно понять инструменты вроде TPL позволяют работать на нужном уровне абстракции. TPL может использовать SynchronizationContext, ThreadPool или создавать новые потоки для планирования задач.
UPD. Почему же не следует использовать Thread.Start. Это слишком низкоуровневое средство, создание потоков дорогое, нужно писать код для отмены вычислений, писать код для проброса исключений вызывающему методу, нужно, кроме того большое количество потоков в системе снижает производительность.
Linq и обход дерева
Простой код для префиксного обхода дерева.
public static class Treenumerable { public static IEnumerable<T> Traverse<T>(this IEnumerable<T> source, Func<T, IEnumerable<T>> childrenSelector) { return source.SelectMany(e => Traverse(e, childrenSelector)); } public static IEnumerable<T> Traverse<T>(T item, Func<T, IEnumerable<T>> childrenSelector) { yield return item; foreach (var subItem in childrenSelector(item).Traverse(childrenSelector)) { yield return subItem; } } }
Чеклист по знания MS SQL 2008
В очередном холиваре на РСДН выкладывал маленький список того что надо знать, чтобы использовать MS SQL эффективно в любой ситуации. Аналогичный чеклист можно сделать для других СУБД. Применять его можно на собеседовании для проверки знаний кандидата.
- Операторы SELECT, INSERT, UPDATE, DELETE, MERGE
- SELECT INTO, INSERT SELECT, OUTPUT clause
- WITH и рекурсивные запросы
- JOIN (inner, left, right, full)
- Встроенные функции: строковые, математические, ranking functions, преобразования типов итп
- Функции: scalar, table, оператор APPLY
- Таблицы и колонки: свойства, вычисляемые и хранимые колонки
- DML триггеры, before, after, insteadof
- View, индексирование View, триггеры на view
- Транзакции, ACID, уровни изоляции
- Ключи, целостность БД
- Нормализация (как минимум до 3 НФ)
- Тип данных, хранение, индексирование, использование (в том числе hierarchyid)
- Индексы, included columns, статистика
- Планы запросов и оптимизация запросов (выбор индекса, подзапросы, функции, агрегаты)
- SELECT FOR XML
- xml тип данных, запросы к ним, индексирование
- BLOBы, хранение и использование, filestream
- spatial data
- Полнотекстовый поиск, contains\containstable, freetext\freetexttable