Reteja Ŝlosila API

Kunordigi laboron kaj uzon de rimedoj inter malsamaj procezoj

Tempo por enŝlosi

Nesinkronaj funkcioj en Ĝavaskripto ne estas vere paralelaj. Komencante kun ES2017, Javascript subtenas samtempajn funkciojn. La diferencon tre bele resumas Madhavan Nagarajan en la sekva aserto (ligo troveblas en la aldono).

Samtempeco temas pri traktado de multaj aferoj samtempe. Paralelismo temas pri fari multajn aferojn samtempe.

La efektivigo de samtempeco de Ĝavaskripto reduktiĝas en sia funkciado por permesi simplan kaj tre fortikan API uzi. Malsinkronaj funkcioj ne povas esti interrompitaj kaj havas neniun koncepton de volatilaj ecoj dum traktado aliron al la sama variablo per malsamaj nesinkronaj vokoj. La detala efektivigo de la asinkronaj funkcioj de ES2017 estas ekster la amplekso de ĉi tiu artikolo, sed la ĉefa punkto, kiun mi volas transdoni, estas, ke ĝis nun paraleleco ne estis enmetita en Ĝavaskripto kaj en la interreto kaj tial neniu speciala pritraktado de paralelaj mutacioj de sama ento. Sed tio ŝanĝiĝas nun kun la enkonduko de la "Interreta Ŝlosila API".

Unu por ĉiuj kaj ĉiuj por unu

Nun kiam progresemaj retaj programoj ofertas al vi verajn multfadenajn arkitekturojn kun la enkonduko de WebWorkers kaj la ServiceWorker, aferoj ŝanĝiĝis. Vera paraleleco eblas en retaj programoj, kaj tial ekestas la deziro pri pli altnivelaj iloj por trakti paralelan kodon.

Seruro estas me mechanismanismo por peti aliron al rimedoj kaj garantii, ke nur unu procezo iam ajn vere havas la aliron. Ŝlosi rimedojn tiamaniere evitas grandan aron da konfliktareoj, kiuj povus alie ekesti.

Rimedo estas nur nomspaco, identigita per ĉeno. Kaj via peto aliri la rimedon estas same simpla, ĉar vi nur bezonas la identigilon kaj funkcian revokon, plej verŝajne nesinkronan, por efektivigi la "Reteblan API". Kiam unu asinkroniga funkcio finiĝis, la seruro liberiĝas kaj aliaj petoj povas aliri ĝin denove.

/*
 * A simple demonstration of the Web Lock API.
 * Note that this example has been taken from
 * MDN's awesome documentation, linked in the
 * addendum.
 */
async function foo(){
  // A common async function that you already know.
  const data = await getData();

  // Request the lock.
  // Note that we can simply await the locked call!
  await navigator.locks.request('lock_resource_id', async lock => {
    // The lock has been acquired.
    // At this point, this call has exlusive access 
    // to the resource 'lock_resource_id'.
    await updateDb(data);
    // Now the lock will be released.
  });
  
  // The lock has been released.
  // Continuse with plain async calls.
  await updateUi();
}

Pro la eksperimenta stato de ĉi tiu nova API, vi devas trakti ĝin kiel nedevigan funkcion en via kodo kun valida rezerva disponebla.

/**
 * Due to the usage of web locks in core parts
 * of your app, actually using the API this way
 * might introduce more problems then it could solve.
 * 
 * Therefore a thorough specification in your app
 * has to be implementation before using this feature.
 */
async function update(){
  if(navigator?.locks){
    // Run logic with lock.
  } else {
    // Use fallback.
  }
}

Por pli bone ilustri ĉi tiun novan API, ni rigardos simplan ekzemplon. Diru, ke vi havas multfadenan PWA kun via ĉefa procezo kaj du Retlaboristoj. Via programo ankaŭ uzas IndexDB, kun kutima kodo, kiu sinkronigas ŝanĝojn al kaj de la datumbazo kun la nubo. Uzante la "Web Lock API" en ĉi tiu scenaro, ĉiu procezo povas peti aliron al la difinita seruro por sinkronigi ŝanĝojn al la datumbazo, certigante, ke neniuj aliaj mutacioj ruliĝos dum ĉi tiu alvoko.

Rimarku, ke la "Reta Ŝlosila API" ne multe temas pri mutado de unu variablo sen kromefikoj en via retejo (kvankam tio klare povas esti uzokazo), sed pli pri traktado de funkciaj alvokoj en paralela arkitekturo, kiu alie kondukus al negativaj kromefikoj.

Multe pli por lerni

Ĉi tiu artikolo nur enkondukis la novan "Retejon Locks API", kiu nuntempe estas en eksperimenta stato kaj ĉefe subtenata de Chromium-bazitaj retumiloj. La API ofertas pli da ebloj, kiuj priskribas ĉi tie, kaj indas rigardi ĝin.