среда, 12 декабря 2012 г.

Архитектура

Есть сущность, которая будет стремиться
Получить автоматизацию в ходе стишка.

На сервере сиквел будет крутиться,
Поддерживающий базу, а в ней уж таблицу,
В которой сущность будет храниться,
Автоматизируемая в ходе стишка.

Класс Entity Framework замаплен в таблицу,
В которой сущность почти что хранится,
Автоматизируемая в ходе стишка.

Возможность была чтоб к таблице пробиться
Сервису SOAP пришлось закрутиться
Который использует класс Entity Framework,
Пишущий данные в тело таблицы,
В которой сущность постоянно хранится,
Автоматизируемая в ходе стишка.

Есть InfoPath-форма, которая, которая злится
Что к сервису придется ей обратиться
Который использует класс Entity Framework,
Пишущий данные в тело таблицы,
В которой сущность возможно хранится,
Автоматизируемая в ходе стишка.

У InfoPath-формы есть код-обработчик
Который использует XPath путь-наводчик
Чтобы записывать данные в поле
Чтобы отправить их сервису что ли?
Чтобы он передал их в класс Entity Framework
Чтобы тот записал их в чудо-таблицу
В которой что-то возможно хранится,
Автоматизируемое в ходе стишка.

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

А так же заказчик, что матерится
При случае не зная к кому обратиться
Когда весь проект под нагрузкой ложится
При эксплуатации автоматизации сущности (по сути ненужности)
Что легла в основу стишка.

среда, 31 октября 2012 г.

Способ сбросить идентификатор элементов в списке Sharepoint

Проблема: после проведения тестирования по добавлению большого количества элементов в список Sharepoint идентификаторы вновь создаваемых элементов имеют неприлично большой размер. Вроде бы ничего страшного, но на кануне большого старта, как-то не по феншую.
Решение: строго говоря, поддерживаемого решения не существует. Все официальные источники рекомендуют пересоздавать список. Однако при большом количестве полей + полей подстановки + рабочих процессов данная рекомендация не подходит.
На просторах интернета было найдено неофициальное решение:
  1. Удалить все элементы из списка
  2. Очистить корзину (вплоть до корзины второго уровня)
  3. На базе с контентом выполнить SQL-скрипт: UPDATE [ContentDB].dbo.AllListsAux set NextAvailableId=1 where ListID='00000000-0000-0000-0000-000000000000', где ContentDB имя Вашей базы с контентом, а 00000000-0000-0000-0000-000000000000 - идентификатор списка.
Решение было опробовано на трех различных списках, проблем не возникло. Однако при применении рекомендую принять все меры предосторожности: потренироваться на тестовом небольшом списке и сделать бекап базы контента.


воскресенье, 28 октября 2012 г.

Нагрузочное тестирование Sharepoint 2010

Исходные данные: Sharepoint 2010 портал, 3000 активных пользователей, база контента около 100 Гб. Железо: 2 WFE, 1 SQL.
Проблема: перед внедрением очередного сайта (а вместе с ним изрядного количества пользователей) проводили нагрузочное тестирование по добавлению большого количества контента на сайт.
Было написано консольное приложение, добавляющее рандомно генерируемые элементы в списки. В три разные списка добавлялись элементы общей численностью чуть более полумиллиона.
Нужно отметить, что проблемы начались сразу после запуска приложения. Периодическое зависание сайта на 10-15секунд, благо запускали перед выходными, и это было не критично. Возникающие фризы списали на работу самой процедуры добавления.
После завершения добавления записей проблема не исчезла. Причем зависание фиксировалось уже на всем семействе сайтов. В течение двух суток пытались определить причины задержек и устранить их. В этот период впервые были зафиксированы пики нагрузки по IO на SQL-сервере.

Причем периодически возникновение пиков (в основном операция чтения 60-100 Мб/сек. на базе с контентом) вызывало рост очереди заданий SQL-сервера. Но не всегда.
Было принято решение об удалении тестового контента. В течении двух последующих суток, ночами, запускалось приложение удаления элементов (как оказалось удалять дольше).
Проблема осталась.
Путем анализа самых дорогих запросов был выявлен SQL-запрос, вызывающий пики, который является частью хранимой процедуры proc_GetChanges базы данных контента.

SELECT TOP (@MaxChanges)
 EventTime,
 Id,
 CASE 
  WHEN (ObjectType = 2048 AND @SiteId IS NOT NULL) 
   THEN @SiteId 
  ELSE 
   SiteId 
 END AS SiteId,
 WebId,
 ListId,
 ItemId,
 DocId,
 Guid0,
 Int0,
 ContentTypeId,
 ItemFullUrl,
 EventType,
 ObjectType,
 TimeLastModified,
 Int1,
 DocClientId
FROM
 TVF_EventCache_GTIdLEQId(@ChangeNumber, @ChangeNumberEnd) AS EC
WHERE
 (EventType & @EventTypeMask) != 0 AND
 (ObjectType & @ObjectTypeMask) != 0
ORDER BY 
 Id ASC

Функция TVF_EventCache_GTIdLEQId обращается к таблице EventCache, которая хранит список всех изменений всех элементов. Таблица, содержала 7,5 миллионов записей, а указанная выборка происходила без учета @SiteId. Исходя из описания данная таблица содержит факты изменения всех элементов для осуществления рассылок. У нас стояла настройка для хранения изменений за 60 дней.

Как оказалось пагубными в нашем случае оказалась совокупность этой настройки и проведенное тестирование с добавлением и последующим удалением элементов.
Решение: изменить настройку на хранение элементов за 7 дней. Настройка располагается здесь: Центр администрирования -> Управление веб-приложениями -> Общие параметры -> Регулирование ресурсов -> Журнал изменений



четверг, 11 октября 2012 г.

Scrolling in Sharepoint Infopath 2010 web form

Проблема: Необходимо создать форму Infopath 2010 для публикации на Sharepoint. В случае если форма содержит несколько представлений (view), при переключении на следующее представление, позиция прокрутки остается на том же месте, где она была в предыдущем представлении.
Поиск решения: Рекомендации не делать больших форм, как решение не подходит. В процессе поиска выяснил, что все формы рендерятся через одну страницу (FormServer.aspx), которая получает в качестве параметра путь к xsn-файлу.
Решение: Добавить в эту страницу javascript-код, который будет скроллировать вверх, если изменялось представление внутри формы. Отслеживание изменения представления ведется через параметр в стилях. В заголовке страницы имеется ссылка вида <link href="http://server/_layouts/FormResource.aspx?solutionId=ваш_ID_похожий_на_base64&amp;view=0&amp;browser=NetscapeStrict&amp;viewFile=View%2Ecss&amp;version=1" type="text/css" rel="stylesheet" />  
Исходя из формата ссылки можно получить активный view и сделать скролл, если он был изменен.
Скрипт, который необходимо добавить в head страницы FormServer.aspx


<script type="text/javascript" src="/_layouts/jquery-1.6.1.min.js"></script>
<script type="text/javascript">
    function foo()
    {
        $("div, html, body").scrollTop(0); 
        // перебор нескольких тегов сделан для учета обычной формы(скроллится div)
        // и формы без риббона шарика (скроллится html)
    }
    var ViewIndex = "";
    $(document).ready(function() {
        var result = /\&amp\;view=(\d+)\&amp\;/.exec($("head").html());
        if (result != null && result.length > 1)
        {
            if (ViewIndex != result[1])
                setTimeout(foo, 100); 
                // почему-то без таймаута скроллинг не срабатывает
            ViewIndex = result[1];
        }
    });
</script>