piscina - node.js工作台

2021-03-24 03:11:06

const路径=要求('路径'); const piscina =要求(' piscina'); const piscina = new piscina({filename:path。解析(__dirname,' worker.js')}); (async函数(){const结果= await piscina。runtask({a:4,b:6});控制台。日志(结果); //打印10})();

const {promisify} =要求(' util'); Const Sleep = ProMisify(Settimout);模块 。导出=异步({a,b})=> {//假冒一些异步活动等待睡眠(100);返回一个+ b; };

从&#39导入{piscina}; piscina' ; const piscina = new piscina({// url必须是文件:// url文件名:新网址(' ./ worker./ worker.mjs',导入meta。url)。href}; (async函数(){const结果= await piscina。runtask({a:4,b:6});控制台。日志(结果); //打印10})();

'使用严格' ; const piscina =要求(' piscina'); const {abortController} =要求('中止控制器'); const {解析} =要求('路径'); const piscina = new piscina({filename:解析(__dirname,' worker.js')}); (async函数(){const abortcontroller = new abortcontroller();尝试{const task = piscina。runtask({a:4,b:6},abortcontroller。信号); abortController。abortController。abort();等待任务;捕获( err){控制台。日志('任务被取消');}});

(在Node.js 15.0.0或更高版本中,还有一个新的内置abortiontrollerimplictation,也可以在此处使用。)

'使用严格' ; const piscina =要求(' piscina'); Const Eventemitter =要求('事件'); const {解析} =要求('路径'); const piscina = new piscina({filename:解析(__dirname,' worker.js')}); (async函数(){const ee = new envertemitter();尝试{const task = piscina。runtask({a:4,b:6},ee); ee。发射('中止');等待任务;} catch(错误){控制台。日志('任务被取消');}});

工人线程不会用于处理任务,直到PiscinadeTermines是" Ready"默认情况下,一旦asisiscina加载它并获取对导出的处理程序函数的引用即可备注。

有时,在工人初始化任何资源时,工人的可用性可能需要延迟,可能需要操作。要支持这种情况,工作模块可能会导出解析vistive处理程序功能而不是直接导出函数:

async函数initialize(){await someasyncinitializationActivity();返回({a,b})=> A + B; } 模块 。导出= initialize();

设置maxqueue选项时,一旦Piscina队列已满,可以提交NoAditional任务,直到队列大小低于Thelimit。 '流失'事件可用于在当水为空时接收通知,并且已将所有任务提交给工人进行处理。

'使用严格' ; const {解析} =要求('路径'); const pool =要求(' ../ ...和ad 39;); const pool =新池({filename:解析(__dirname,' worker.js'),maxqueue:'自动'}); const Stream = GetStreamSomeHow();溪流 。 setencoding(' utf8');水池 。在('漏极和#39;()=> {if(stream。ispaused()){控制台。日志('恢复...'柜台,池。排队);流。Resume();}});溪流 。在('数据'(数据)=> {池。runtask(数据);如果(池。queuesize ===池。选项。maxqueue){控制台。日志('暂停。 ..',计数器,池。queue化);流。暂停();}})。 ON('错误',控制台。错误)。在(' ext',()=> {控制台。日志(' done');

Piscina通过创建一个节点.js工作池,可以调度到哪个或更多任务。每个工作线程在单独文件中执行asingle导出的函数。每当atask被调入工作者时,工作者都会调用导出功能,并在函数完成时将返回值报告回Piscina。

支持以下可选配置:filename :( String | null)为代码提供了ThomRuns在工作线程上的任务的默认源。这应该是一个绝对路径或AnaBsolute文件:// filed for oc属于将JavaScript函数或async函数导出为其默认导出或module.exports的文件。 es moduesare支持。

minthreads :( number)设置始终为此线程池的最小线程数。默认值基于AVailable CPU的数字。

maxthreads :( number)设置为此线程池进行arerunning的最大线程数。默认值基于AVailable CPU的数字。

iDletimeout :( number)以毫秒为单位,指定允许Wonga Worker如何空闲,即在ISShut之前不处理任何任务。默认情况下,这是立即的。提示:默认的idleyoutcan导致应用程序中的某些性能损失,因为停止和启动新的工人线程过度播放。要提高性能,请尝试显式设置iDletimeout。

maxqueue :(字符串)可以陷入困境的最大任务数,但尚未由于缺少可用的线程而尚未运行,则给定时间。默认情况下,没有限制。特殊价值'自动'可用于有piscina计算最大值作为maxthreads的正方形。当'自动'使用,可以通过检查选项.MaxQueue属性来找到计算的克苏索值。

ConcurrentTasksperWorker:(Number)指定Sharea Single Worker线程可以同时使用多少任务。默认值为1.这一般地是有意义的,以指定是否存在某种异步组件对任务。请记住,工人线程通常并行地构建了i / o。

vereatomics :( boolean)使用原子学API更快的Companical2线程。默认情况下,这是开启的。

resourcelimits :(对象)请参阅node.js新工作人员选项stacksizemb :( number)线程的默认最大堆栈大小.Small值可能导致无法使用的工人实例。默认值:4

env :(对象)如果设置,则指定process.env Insidethe Worker线程的初始值。有关详细信息,请参阅Node.js新工人选项。

argv :(任何[])将被串联和附加到工人的Process.argv的参数列表。有关详细信息,请参阅Node.js新工人选项。

EXECARGV :( String [])节点.js CLI选项的列表传递给Worker.see node.js新的工作者选项有关详细信息。

WorkerData:(任何)任何可以克隆的JavaScript值和MeDeavaulable,因为需要(' piscina')。工作者。请参阅Node.js New Worker options以详细信息。与常规Node.js Worker线程不同,WorkerData必须指定需要传送列表的任何值。这是因为克隆了每个合并的工作者的人员。

TaskQueue :( TaskQueue)默认情况下,Piscina使用了一个先进的任务的第一张外外。 TaskQueue选项可用于提供分析实现。有关其他详细信息,请参阅自定义任务队列。

NiceIncrement :(编号)一个可选的值,即在单个线程中减少优先级,即,值越高,工作线程的优先级越低。此值仅在Linux上使用,并需要安装Aptigional Nice-NAPI模块。将(2)欣赏到更多详细信息。

trackunmanagedfds :( boolean)一个可选的设置,当为true时,将跟踪使用fs.open()和fs.close()管理的文件描述符的工人,并且当工作员退出到true时将自动关闭它们。 (此选项仅在高于14.6.0的Node.js 12.19+和所有Node.js版本上支持。

设置资源限制时要小心。在Piscina工人线程中的梅雷曲板太低的设定限制是无法使用的。

传输列表:将任务发布到工作人员时传递给[PostMessage()]的可选对象列表,这些对象将转移到TransfortRather而不是克隆。

filename:可选地覆盖传递给theconstructor的文件名选项以获取此任务。如果没有将文件名指定给构造函数,则这是强制性的。

abortsignal:[abortsignal] []实例。如果通过,这可以用来使用tocancel一个任务。如果任务已经运行,则将停止相应的工作者。(更一般地,发出&#39的任何EventEmitter或EventTarget;中止'事件可以通过此处传递。

这返回了从文件名导出的函数的(async)函数callmade返回值的承诺。如果(async)函数划分错误,则返回的承诺将被拒绝使用该错误。如果任务中止,则返回的承诺将被错误拒绝。

通过拒绝从runtask()返回的承诺来报告所有其他错误,包括处理程序函数本身报告的拒绝。

此实例当前使用的选项的副本。此object属于与构造函数传递的选项对象相同的属性。

总结完成任务的RUND时间的直方图摘要对象。所有值都以毫秒表示。

模式p {n}之后的所有属性,其中n是数字(例如p1,p99)表示运行时间观测的百分位分布。例如,P99是第99个百分位数,表明观察到的运行时间的99%尚不到或等于给定值。

{平均:1880.25,STDDEV:1.93,MIN:1877,MAX:1882.0190887451172,P0_001:1877,P0_01:1877,P0_1:1877,P1:1877,P2_5:1877,P10:1877,P50:1877,P50 :1881,P75:1881,P90:1882,P97_5:1882,P99:1882,P99_9:1882,P99_99:1882,P99_999:1882}

将近似总均值均值均值的时间比较与池总运行时容量进行比较。

通过将optionBy.MaxThread计数乘以乘以乘以汇率来确定池运行时容量。这提供了绝对的理论上的聚合计算池能够的计算时间。

通过将所有已完成任务的全部完成任务的总数乘以所有已完成的任务的乘积来确定近似总平均运行时间。此数字表示近似的THEPOOL一直在主动处理任务。

然后通过将近似总芯片运行时间除以容量来计算利用,从而产生0到1之间的分数。

总结在队列中占用的收集时间任务的直方图摘要对象。所有值都以毫秒表示。

模式p {n}之后的所有属性,其中n是数字(例如p1,p99)表示等待时间观察的百分位分布。例如,P99是第99个百分位数,表明99%的观察到的等待时间尚不到或等于给定值。

{平均:1880.25,STDDEV:1.93,MIN:1877,MAX:1882.0190887451172,P0_001:1877,P0_01:1877,P0_1:1877,P1:1877,P2_5:1877,P10:1877,P50:1877,P50 :1881,P75:1881,P90:1882,P97_5:1882,P99:1882,P99_9:1882,P99_99:1882,P99_999:1882}

默认情况下,即使该对象能够转移,也将克隆回Piscina池时克隆任何由工作函数返回的任何值。 piscina.move()方法可用于包装和标记可传输的值,使得它们将通过传输而不是传输。

该值可以是Node.js支持的任何对象以可转换(例如,ArrayBuffer,任何TymedArray或MessagePort),或任何Objectimplementing可转换接口。

移动()方法返回的对象不应将其设置为对象中的敏感值。如果使用它,则移动()对象本身克隆,而不是将其包裹的对象传输。

对象可以实现可转换的接口以创建其AnyCuStom可转移对象。当呈向或从工作者呈现的对象包含深度嵌套的转换诸如ArrayBuffer或MessagePort时,这非常有用。

可转移物体暴露了Piscinato检测的两个属性,确定如何传输对象。这些属性使用特殊的静态piscina.transferablesymbol和piscina.valuesymbol属性:

piscina.transferablesymbol属性提供要包含在传送列表中的对象(或对象)。

const {move,transferablesymbol,supersymbol} =要求(' piscina');模块 。 Exports =()=> {const obj = {a:{b:new uint8array(5); },C:{新UINT8ARRAY(10); },get [transferablesymbol](){//传输两个底层的arroundBuffers返回[此。一种 。湾缓冲区,这个。 C 。缓冲 ] ;获取[值ymbol](){return {a:{b:this。一种 。 b},c:这。 C } ; }};返回移动(obj); };

默认情况下,Piscina使用简单的基于数组的首先(FIFO)任务队列。提交新任务并没有可用的工作者时,将推送到队列,直到工作者成为可用。

如果默认的FIFO队列不够,则用户代码可以使用Piscina构造函数上的TaskQueSue选项用自定义实现替换Thetask队列实现。

接口任务{readonly [piscina。 QueueOptionsSymbol]:对象|空值 ; }接口TaskQueue {ReadOnly Size:Number; Shift():任务|空值 ;删除(任务:任务):void;推(任务:任务):void; }

使用示例/任务队列中可用的Shubububled Priority Queueis的自定义任务队列的示例;

特殊符号piscina.queueOptionsSymbol可以设置为提交给RunTask()的浮标任务,作为将其他替代单传递给自定义TaskQueue实现的方式。 (请注意,由于“当时”选项“设置为”任务“中的属性,因此无法将带有队列选项的任务作为JavaScript语义提交)。

工人通常优化用于从主节点事件循环线程中卸载同步,计算密集型操作。虽然可以执行异步操作和I / OWITHIN一个工作人员,但这样做的性能优势将Beminimal。

具体而言,值得注意的是,异步操作With Node.js,包括文件系统操作函数CPU绑定任务,例如加密操作或压缩仪,这些任务已经由每个过程级别的Node.js和Libuv并行地执行。这意味着会贬低对Piscina工人移动这种诸如异步操作的性能影响(例如,参见示例/杂文)。

Piscina提供了配置池中活动的最小和最大数量的工作线程的能力,以及可以排队等待自由工作者的任务数量的资产限制。重要的是要注意,将Maxqueue尺寸相对于工作人员的数量太高,对性能和内存使用产生了有害影响。静态尺寸太小也可能是有问题的,因此可能导致你的工作线变得闲置关掉。我们的测试表明,Maxqueue大小的大小千分之夸的线程的平方是出色的,对于许多情况来说,对于许多情况来说,但这都是根据你的工作量而差异很大。测试和基准测试和基准,以确保您' VEEFFective平衡队列等待时间,内存用法和WorkerPool利用率。

由Piscina维护的线程池具有最小值和最大值,可以创建的线程数。创建PiscinainStance时,它将产生最小线程数,然后根据MaxThreads设置的Thelimit,创建其他线程。每当工人完成任务时,就会确定ACheck以确定是否有额外的工作。如果没有额外的工作,则线程标记为空闲.By默认值,立即关闭空闲线程,池仍然保持最小值。

当Piscina池正在处理任务流(例如,在示例/ React-SSR中的React Server-SircleDendering示例中处理HTTP服务器请求时),如果接收到新任务的速率并排队不足以保持工作人员闲置和终止,游泳池可以遇到ThrashingEffect - 过度创建和终止工人遗漏净性能损失。有几种策略tavoid这次流失:

策略1:确保新任务的队列率足以闲置的工人。我们将此称为"队列压力"。如果队列压力太低,工人将闲置并终止。如果队列压力太高,则任务将堆叠,versiancread等待延迟,并占用额外的等待延迟记忆。

策略2:增加idlemout配置选项。 bydefault,空闲线程立即终止。 IDLETIMEOUT OptionCan可用于指定更长的时间段等待在终止工作人员之前要提交的其他要素。如果没有维护队列压力,这可能导致坐着的工人坐着,当线程重复终止和重新创建时,那些将缺乏的性能撞击的性能影响。

策略3:增加Minthreads配置选项。这具有与增加Idletimeout的基本效果相同。如果队列压力不够高,工人可能无限期地闲置,但仍将达到绩效令人沮丧。

在使用Piscina的应用中,使用这三种方法的丙蛋白是最有效的,并调整各种配置参数,以找到应用程序加载和部署环境的功能的最佳组合。 Oreare没有一套选择最好的选择。

在支持Nice(2)的Linux系统上,Piscina能够在池中的每个工人设置优先级。要使用此机制,需要一个其他可选的本机addon依赖项(Nice-Napi,NPM i Nice-Napi)。安装了Nice-Napi,使用NicePcrement配置选项创建Piscina实例将设置池的优先级:

NicePecrement越高,CPU调度优先级的较低工人将是汇总的工人,它通常会扩展到跨界任务的执行时间,但有助于防止这些线程从主节点事件循环线程窃取CPU时间。无论这是一件好事还是不依赖于您的申请,并需要仔细的分析以获得正确。

关键指标要注意调整NicePecrement时是工作池中任务的按次运行时间(使用RuntimeProperty)和Node.js主线程事件循环的延迟。

每个Piscina实例都会创建一个单独的线程池,并操作其他对方的任何意识。当在ASICE应用程序中创建多个池时,各种线程可以彼此竞争,并且具有Node.js主事件循环线程,并且可能导致整体证明系统性能。

嵌入Piscina作为依赖性的模块应该使其清除使用线程的虚拟度量。如果有可能为用户提供提供的人,那将是理想的

......