Я прослушивал TJ на node-canvasоб ускорении кода, над которым я работаю в форке модуля узла, который он создал и поддерживает.
Я обнаружил, что Canvas.toBuffer() убивает ресурсы нашего конвейера, и создал альтернативу, которая просто преобразует Canvas в изображение, не проходя через буфер png / URL-адрес носителя. Проблема в том, что cairo — это таинственный зверь, и существует дополнительный уровень беспокойства по поводу памяти, выделенной в модулях узлов, чтобы не получить GC'd от матери v8. Я добавил соответствующие HandleScopes ко всем необходимым функциям, которые получают доступ к данным V8.
Я смог протестировать метод Canvas.loadImage(image) тысячи раз в моей установке Mac (6.18), а также автономные тесты на наших серверах ubuntu / production, работающих под управлением той же версии узла. Но когда код запускается как фоновый процесс/сервер и координируется Gearman, я получаю некоторые «интересные» модули памяти/segfaults.
Кроме того, у меня возникают проблемы с вызовом любого из методов классов, определенных в node-canvas, которые не встроены в заголовочные файлы. В качестве побочного вопроса Как лучше всего создавать общие пакеты исходного кода, на которые могут положиться другие модули узлов?
Я попытался воссоздать проблему и запустить ее с помощью gdb, node_g и всех модулей узлов, построенных с помощью символов и отладочных флагов. Но ошибка возникает в lib за пределами источника, для которого я могу получить трассировку стека.
Для справки вот где я вызываю loadImageData, и хотя он работает локально в различных условиях, в нашей производственной среде, когда он тщательно спрятан в фрейм-сервере, он, по-видимому, вызывает segfaults (вчера провел день, пытаясь gdb node_g наш серверный код, но фрейм-серверы запускаются gearman... TL;DR не получил трассировку стека основных причин)
https://github.com/victusfate/node-canvas/blob/master/src/Canvas.cc#L497
Handle
Canvas::LoadImage(const Arguments &args) {
HandleScope scope;
LogStream mout(LOG_DEBUG,"node-canvas.paint.ccode.Canvas.LoadImage");
mout << "Canvas::LoadImage top " << LogStream::endl;
Canvas *canvas = ObjectWrap::Unwrap
и вот как выглядит текущий метод в Image (я удалил некоторые закомментированные сведения о журнале) https://github.com/victusfate/node-canvas/blob/master/src/Image.cc#L240
/*
* load from data buffer width*height*4 bytes
*/
cairo_status_t
Image::loadFromDataBuffer(uint8_t *buf, int width, int height) {
this->clearData();
int stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, width); // 4*width + ?
this->_surface = cairo_image_surface_create_for_data(buf,CAIRO_FORMAT_ARGB32,width,height,stride);
this->data_mode = DATA_IMAGE;
this->loaded();
cairo_status_t status = cairo_surface_status(_surface);
if (status) return status;
return CAIRO_STATUS_SUCCESS;
}
Мы будем признательны за любую помощь, профессиональные советы, содействие или слова ободрения.
Родом из групп Google