Кросс-AppDomain вызов производительности со сложными объектами - PullRequest
0 голосов
/ 28 ноября 2018

Приложение, над которым я работаю, позволяет пользователям предоставлять свой собственный код, который они создают на основе предоставленного нами API.Недавно мы переместили выполнение пользовательского кода в отдельный домен приложений из соображений безопасности.Предоставляемый нами API передает потребителю граф объектов (POCO), содержащий более 100 тыс. Объектов.Когда этот объект пересекает границу AppDomain, все эти данные сериализуются / десериализуются с использованием BinaryFormatter.

  • BinaryFormatter имеет значение медленно - O (n²) - это обычно дляСериализатору отводится 1+ минуты на сериализацию / десериализацию.

  • Мы не можем изменить API, не вызвав много поломок, поэтому мы, скорее всего, застряли с ним.

До сих пор я пробовал следующее:

  • Пометить модель, которая была передана как MarshalByRefObject.Это вызывает еще большую деградацию, поскольку при каждом доступе к свойству в модели все данные этого свойства сериализуются;вызывая дополнительные издержки сериализации / десериализации.

  • Вставить / распаковать модель, переданную с контейнером, который использует MessagePack / Protobuf-net для сериализации.В моих модульных тестах сериализация работает намного лучше (например, 60 -> 5 секунд).Однако при его фактическом использовании в ограниченном домене приложений десериализация завершается неудачно из-за ограничений безопасности.

Некоторые мысли:

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

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

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

  • Мне принадлежит объект в клиентском домене приложений, который проксируется в серверный домен приложений.Затем этот объект вызывает код пользователя (через шаблон RazorEngine).

Поэтому мой вопрос состоит в том, что я могу сделать, чтобы повысить производительность вызова кода пользователя при сохранении текущего APIи сохранить разделение, обеспечиваемое вторичным доменом приложений?

...