TypeScript-এ `Shared Worker`

এই প্রবন্ধে TypeScript-এ Shared Worker ব্যাখ্যা করা হয়েছে।

TypeScript কোড উদাহরণসহ Shared Worker কীভাবে কাজ করে এবং বাস্তবে কীভাবে ব্যবহার করবেন তা বিস্তারিতভাবে ব্যাখ্যা করব।

YouTube Video

TypeScript-এ Shared Worker

Shared Worker হচ্ছে একই origin-এর একাধিক ট্যাব, উইন্ডো এবং iframe-এর মধ্যে শেয়ার করা একটি একক worker প্রক্রিয়া। এটি ব্যবহার করে আপনি একাধিক ব্রাউজার ট্যাব জুড়ে শেয়ার করা স্টেট ও রিসোর্স পরিচালনা করতে পারেন।

উদাহরণস্বরূপ, আপনি কার্যকরভাবে শেয়ার করা WebSocket সংযোগ, ট্যাবজুড়ে সমন্বিত cache ও queue প্রক্রিয়াকরণ, এবং mutual exclusion বাস্তবায়ন করতে পারেন।

Dedicated Worker-এর বিপরীতে, Shared Worker onconnect ইভেন্টের মাধ্যমে একাধিক MessagePort গ্রহণ করে এবং একাধিক ক্লায়েন্টের সাথে যোগাযোগগুলোকে মাল্টিপ্লেক্স করতে পারে।

যে ক্ষেত্রে আপনি Shared Worker বেছে নেবেন

নিচের ক্ষেত্রে Shared Worker ব্যবহার করা উপযুক্ত।

  • ট্যাবজুড়ে শেয়ার করা স্টেট বা মিউচুয়াল এক্সক্লুশন প্রয়োজন হলে
  • একটি WebSocket সংযোগ বা IndexedDB অ্যাক্সেস শেয়ার করতে চাইলে
  • সব ট্যাবকে জানাতে (ব্রডকাস্ট) হলে
  • রিসোর্স বাঁচাতে ভারী প্রসেসিং কেন্দ্রীভূত করতে চাইলে

অন্যদিকে, নিচের ক্ষেত্রে ভিন্ন পদ্ধতি বেশি উপযুক্ত।

  • যখন ক্যাশ নিয়ন্ত্রণ বা অফলাইন সমর্থন প্রয়োজন, তখন আপনি Service Worker ব্যবহার করতে পারেন।
  • একটি মাত্র ট্যাবের মধ্যে সীমাবদ্ধ ভারী প্রক্রিয়াকরণের জন্য, আপনি Dedicated Worker ব্যবহার করতে পারেন।

Shared Worker-এর বাস্তবায়ন ধাপসমূহ

এখানে আমরা TypeScript ব্যবহার করে ধাপে ধাপে নিচেরগুলো ইমপ্লিমেন্ট করব।

  • টাইপ-সেফ মেসেজ প্রোটোকল
  • প্রমিজ-ভিত্তিক রিকোয়েস্ট/রেসপন্স (RPC)
  • সব ট্যাবে ব্রডকাস্ট
  • হার্টবিট ও ক্লায়েন্ট ক্লিনআপ

পরিবেশ সেটআপ

Shared Worker ব্যবহার করা প্রতিটি সোর্স ফাইল কম্পাইল করার জন্য কনফিগারেশন তৈরি করুন।

 1{
 2  "compilerOptions": {
 3    "target": "ES2020",
 4    "module": "ES2020",
 5    "lib": ["ES2020", "dom", "WebWorker"],
 6    "moduleResolution": "Bundler",
 7    "strict": true,
 8    "noEmitOnError": true,
 9    "outDir": "out",
10    "skipLibCheck": true
11  },
12  "include": ["src"]
13}
  • tsconfig-src.json-এ, DOM এবং Web Worker-এর টাইপ ডেফিনিশন সক্রিয় করুন যাতে কোডটি নিরাপদে কম্পাইল করা যায়।

মেসেজ প্রোটোকল সংজ্ঞা

যোগাযোগের ভিত্তি হলো একটি টাইপযুক্ত মেসেজ কন্ট্র্যাক্ট। এটি আগেই সংজ্ঞায়িত করলে পরবর্তী যোগাযোগ নিরাপদ হয় এবং সহজে সম্প্রসারণ করা যায়।

 1// worker-protocol.ts
 2// Define discriminated unions for structured messages
 3
 4export type RequestAction =
 5  | { type: 'ping' }
 6  | { type: 'echo'; payload: string }
 7  | { type: 'getTime' }
 8  | { type: 'set'; key: string; value: unknown }
 9  | { type: 'get'; key: string }
10  | { type: 'broadcast'; channel: string; payload: unknown }
11  | { type: 'lock.acquire'; key: string; timeoutMs?: number }
12  | { type: 'lock.release'; key: string };
  • RequestAction একটি discriminated union (tagged union), যা worker-এ পাঠানো অনুরোধের ধরনগুলো উপস্থাপন করে এবং ping, get, ও broadcast প্রভৃতি অপারেশন সংজ্ঞায়িত করে।
1export interface RequestMessage {
2  kind: 'request';
3  id: string;
4  from: string;
5  action: RequestAction;
6}
  • RequestMessage ক্লায়েন্ট থেকে ওয়ার্কারের কাছে পাঠানো অনুরোধ বার্তার কাঠামো সংজ্ঞায়িত করে।
1export interface ResponseMessage {
2  kind: 'response';
3  id: string;
4  ok: boolean;
5  result?: unknown;
6  error?: string;
7}
  • ResponseMessage ওয়ার্কার থেকে ক্লায়েন্টে ফেরত আসা প্রতিক্রিয়া বার্তার কাঠামো সংজ্ঞায়িত করে।
1export interface BroadcastMessage {
2  kind: 'broadcast';
3  channel: string;
4  payload: unknown;
5  from: string;
6}
  • BroadcastMessage ওয়ার্কার অন্যান্য ক্লায়েন্টকে যে সম্প্রচার বার্তা পাঠায় তার কাঠামো সংজ্ঞায়িত করে।
1export type WorkerInMessage =
2  | RequestMessage
3  | { kind: 'heartbeat'; from: string }
4  | { kind: 'bye'; from: string };
  • WorkerInMessage এমন একটি টাইপ যা ওয়ার্কার যে সব বার্তা গ্রহণ করে—যেমন অনুরোধ, হার্টবিট, এবং সংযোগ-বিচ্ছিন্নতার নোটিফিকেশন—সেগুলো উপস্থাপন করে।
1export type WorkerOutMessage = ResponseMessage | BroadcastMessage;
  • WorkerOutMessage এমন একটি টাইপ যা ওয়ার্কার ক্লায়েন্টকে যে প্রতিক্রিয়া বা সম্প্রচার বার্তা পাঠায় তা উপস্থাপন করে।
1export const randomId = () => Math.random().toString(36).slice(2);
  • randomId এমন একটি ফাংশন যা বার্তা ID ইত্যাদির জন্য ব্যবহারের উদ্দেশ্যে একটি এলোমেলো অ্যালফানিউমেরিক স্ট্রিং তৈরি করে।

Shared Worker বাস্তবায়ন

shared-worker.ts-এ, onconnect ইভেন্টের মাধ্যমে যুক্ত হওয়া ট্যাবগুলো রেজিস্টার করুন এবং মেসেজ হ্যান্ডল করুন।

1// shared-worker.ts
2/// <reference lib="webworker" />
  • এই নির্দেশটি TypeScript-কে Web Worker-গুলোর টাইপ ডেফিনিশন লোড করতে বলে।
1import {
2  WorkerInMessage,
3  WorkerOutMessage,
4  RequestMessage,
5  ResponseMessage,
6} from './worker-protocol.js';
  • ওয়ার্কার যোগাযোগে ব্যবহৃত টাইপ ডেফিনিশনগুলো ইমপোর্ট করে।
1export default {};
2declare const self: SharedWorkerGlobalScope;
  • স্পষ্টভাবে ঘোষণা করে যে self হল Shared Worker-এর গ্লোবাল স্কোপ।
1type Client = {
2  id: string;
3  port: MessagePort;
4  lastBeat: number;
5};
  • Client এমন একটি টাইপ যা প্রতিটি ক্লায়েন্টের শনাক্তকারী, যোগাযোগের পোর্ট, এবং সর্বশেষ হার্টবিটের টাইমস্ট্যাম্প উপস্থাপন করে।
1const clients = new Map<string, Client>();
2const kv = new Map<string, unknown>();
3const locks = new Map<string, string>();
4const HEARTBEAT_TIMEOUT = 30_000;
  • সংযুক্ত ক্লায়েন্টদের তালিকা, একটি কী-ভ্যালু স্টোর, লকের অবস্থা, এবং টাইমআউটের সময়কাল পরিচালনা করে।
1function send(port: MessagePort, msg: WorkerOutMessage) {
2  port.postMessage(msg);
3}
  • send এমন একটি ইউটিলিটি ফাংশন যা নির্দিষ্ট পোর্টে একটি বার্তা পাঠায়।
1function respond(req: RequestMessage, ok: boolean, result?: unknown, error?: string): ResponseMessage {
2  return { kind: 'response', id: req.id, ok, result, error };
3}
  • respond একটি অনুরোধের জন্য প্রতিক্রিয়া বার্তা তৈরি করে।
1function broadcast(from: string, channel: string, payload: unknown) {
2  for (const [id, c] of clients) {
3    send(c.port, { kind: 'broadcast', channel, payload, from });
4  }
5}
  • broadcast নির্দিষ্ট চ্যানেলে সকল ক্লায়েন্টকে একটি বার্তা পাঠায়।
1function handleRequest(clientId: string, port: MessagePort, req: RequestMessage) {
  • handleRequest টাইপ অনুসারে আগত অনুরোধগুলো প্রক্রিয়া করে এবং ফলাফল ক্লায়েন্টকে ফেরত দেয়।
 1  const { action } = req;
 2  try {
 3    switch (action.type) {
 4      case 'ping':
 5        send(port, respond(req, true, 'pong'));
 6        break;
 7      case 'echo':
 8        send(port, respond(req, true, action.payload));
 9        break;
10      case 'getTime':
11        send(port, respond(req, true, new Date().toISOString()));
12        break;
13      case 'set':
14        kv.set(action.key, action.value);
15        send(port, respond(req, true, true));
16        break;
17      case 'get':
18        send(port, respond(req, true, kv.get(action.key)));
19        break;
20      case 'broadcast':
21        broadcast(clientId, action.channel, action.payload);
22        send(port, respond(req, true, true));
23        break;
  • এই কোডে, প্রাপ্ত অনুরোধের ধরন অনুযায়ী বার্তা প্রেরণ ও গ্রহণ, ডেটা আহরণ ও সংরক্ষণ, এবং ব্রডকাস্টিং পরিচালিত হয়।
 1      case 'lock.acquire': {
 2        const owner = locks.get(action.key);
 3        if (!owner) {
 4          locks.set(action.key, clientId);
 5          send(port, respond(req, true, { owner: clientId }));
 6        } else if (owner === clientId) {
 7          send(port, respond(req, true, { owner }));
 8        } else {
 9          const start = Date.now();
10          const tryWait = () => {
11            const current = locks.get(action.key);
12            if (!current) {
13              locks.set(action.key, clientId);
14              send(port, respond(req, true, { owner: clientId }));
15            } else if ((action.timeoutMs ?? 5000) < Date.now() - start) {
16              send(port, respond(req, false, undefined, 'lock-timeout'));
17            } else {
18              setTimeout(tryWait, 25);
19            }
20          };
21          tryWait();
22        }
23        break;
24      }
  • এই কোডটি নির্দিষ্ট কী-এর জন্য কোনো ক্লায়েন্টের লক অধিগ্রহণের প্রক্রিয়া বাস্তবায়ন করে। লকটি যদি ইতিমধ্যে ধরে রাখা না থাকে, তবে তা সঙ্গে সঙ্গে অধিগ্রহণ করা হয়; একই ক্লায়েন্ট আবার অনুরোধ করলে সেটিকেও সফল হিসেবে গণ্য করা হয়। অন্য কোনো ক্লায়েন্ট যদি ইতিমধ্যে লকটি ধরে রাখে, তবে লক মুক্ত না হওয়া পর্যন্ত এটি প্রতি ২৫ মিলিসেকেন্ডে পুনরায় চেষ্টা করে; এবং নির্দিষ্ট টাইমআউট (ডিফল্ট ৫ সেকেন্ড) অতিক্রম করলে এটি একটি ত্রুটি সহ সাড়া দেয়।
 1      case 'lock.release':
 2        if (locks.get(action.key) === clientId) {
 3          locks.delete(action.key);
 4          send(port, respond(req, true, true));
 5        } else {
 6          send(port, respond(req, false, undefined, 'not-owner'));
 7        }
 8        break;
 9      default:
10        send(port, respond(req, false, undefined, 'unknown-action'));
11    }
12  } catch (e: any) {
13    send(port, respond(req, false, undefined, e?.message ?? 'error'));
14  }
15}
  • এই কোডটি ক্লায়েন্টের দখলে থাকা লক মুক্ত করে এবং ক্লায়েন্টের অনুমতি না থাকলে বা ক্রিয়াটি অজানা হলে একটি ত্রুটি প্রতিক্রিয়া ফেরত দেয়।
1function handleInMessage(c: Client, msg: WorkerInMessage) {
2  if (msg.kind === 'heartbeat') {
3    c.lastBeat = Date.now();
4  } else if (msg.kind === 'bye') {
5    cleanupClient(msg.from);
6  } else if (msg.kind === 'request') {
7    handleRequest(c.id, c.port, msg);
8  }
9}
  • handleInMessage ক্লায়েন্টদের থেকে প্রাপ্ত বার্তা পার্স করে এবং অনুরোধ ও হার্টবিট পরিচালনা করে।
1function cleanupClient(clientId: string) {
2  for (const [key, owner] of locks) {
3    if (owner === clientId) locks.delete(key);
4  }
5  clients.delete(clientId);
6}
  • cleanupClient রেজিস্ট্রি ও লকের অবস্থা থেকে সংযোগ-বিচ্ছিন্ন ক্লায়েন্টদের সরিয়ে দেয়।
1setInterval(() => {
2  const now = Date.now();
3  for (const [id, c] of clients) {
4    if (now - c.lastBeat > HEARTBEAT_TIMEOUT) cleanupClient(id);
5  }
6}, 10_000);
  • setInterval ব্যবহার করে নির্দিষ্ট সময় পরপর সকল ক্লায়েন্টের হার্টবিট পরীক্ষা করে এবং টাইমআউট হয়ে যাওয়া সংযোগগুলো পরিষ্কার করে।
 1self.onconnect = (e: MessageEvent) => {
 2  const port = (e.ports && e.ports[0]) as MessagePort;
 3  const clientId = crypto.randomUUID?.() ?? Math.random().toString(36).slice(2);
 4  const client: Client = { id: clientId, port, lastBeat: Date.now() };
 5  clients.set(clientId, client);
 6
 7  port.addEventListener('message', (ev) => handleInMessage(client, ev.data as WorkerInMessage));
 8  send(port, { kind: 'broadcast', channel: 'system', payload: { hello: true, clientId }, from: 'worker' });
 9  port.start();
10};
  • Shared Worker-এ নতুন ট্যাব বা পেজ সংযুক্ত হলে onconnect কল হয়; এটি ক্লায়েন্ট রেজিস্টার করে এবং যোগাযোগ শুরু করে।

  • এই ফাইল জুড়ে, একাধিক ব্রাউজার ট্যাবের মধ্যে শেয়ারড স্টেট ম্যানেজমেন্ট ও যোগাযোগ সক্ষম করার জন্য Shared Worker-এর মৌলিক প্রক্রিয়াগুলো বাস্তবায়িত হয়েছে।

ক্লায়েন্ট র‍্যাপার (RPC)

এরপর, একটি প্রমিজ-ভিত্তিক RPC ক্লায়েন্ট তৈরি করুন।

1// shared-worker-client.ts
2import {
3  RequestAction,
4  RequestMessage,
5  WorkerOutMessage,
6  randomId
7} from './worker-protocol.js';
  • ওয়ার্কার যোগাযোগে ব্যবহৃত টাইপ ডেফিনিশন ও ইউটিলিটি ফাংশনগুলো ইমপোর্ট করে।
1export type BroadcastHandler = (msg: {
2  channel: string;
3  payload: unknown;
4  from: string
5}) => void;
  • এখানে আমরা এমন কলব্যাক ফাংশনের টাইপ সংজ্ঞায়িত করি, যা একটি সম্প্রচার বার্তা পাওয়া গেলে চালিত হয়।
1export class SharedWorkerClient {
  • SharedWorkerClient হল একটি ক্লায়েন্ট ক্লাস, যা Shared Worker-এর সঙ্গে যোগাযোগ করে, অনুরোধ পাঠায় এবং প্রতিক্রিয়া পরিচালনা করে।
1  private worker: SharedWorker;
2  private port: MessagePort;
3  private pending = new Map<string, {
4    resolve: (v: any) => void;
5    reject: (e: any) => void
6  }>();
  • এই চলকগুলো হলো ওয়ার্কার ইনস্ট্যান্স, ওয়ার্কারের সঙ্গে যোগাযোগের পোর্ট, এবং এমন একটি ম্যাপ যা প্রতিক্রিয়ার অপেক্ষায় থাকা অনুরোধগুলো ট্র্যাক করে।
1  private clientId = randomId();
2  private heartbeatTimer?: number;
3  private onBroadcast?: BroadcastHandler;
  • এই চলকগুলোতে ক্লায়েন্টের শনাক্তকারী, হার্টবিট পাঠানোর টাইমার, এবং সম্প্রচার গ্রহণের হ্যান্ডলার সংরক্ষিত থাকে।
1  constructor(url: URL, name = 'app-shared', onBroadcast?: BroadcastHandler) {
2    this.worker = new SharedWorker(url, { name, type: 'module' as any });
3    this.port = this.worker.port;
4    this.onBroadcast = onBroadcast;
  • কন্সট্রাক্টরে, এটি Shared Worker-এ সংযোগ আরম্ভ করে এবং বার্তা শ্রোতা (listener) ও হার্টবিট পাঠানো সেট আপ করে।
 1    this.port.addEventListener('message', (ev) => {
 2      const msg = ev.data as WorkerOutMessage;
 3      if (msg.kind === 'response') {
 4        const p = this.pending.get(msg.id);
 5        if (p) {
 6          this.pending.delete(msg.id);
 7          msg.ok ? p.resolve(msg.result) : p.reject(new Error(msg.error || 'error'));
 8        }
 9      } else if (msg.kind === 'broadcast') {
10        this.onBroadcast?.(msg);
11      }
12    });
13    this.port.start();
  • এখানে এটি ওয়ার্কার থেকে বার্তা গ্রহণ করে এবং প্রতিক্রিয়া বা সম্প্রচার পরিচালনা করে।
1    this.heartbeatTimer = window.setInterval(() => {
2      this.port.postMessage({ kind: 'heartbeat', from: this.clientId });
3    }, 10_000);
  • সংযোগ সচল রাখতে নির্দিষ্ট বিরতিতে হার্টবিট বার্তা পাঠায়।
1    window.addEventListener('beforeunload', () => {
2      try {
3        this.port.postMessage({ kind: 'bye', from: this.clientId });
4      } catch {}
5      if (this.heartbeatTimer) clearInterval(this.heartbeatTimer);
6    });
7  }
  • উইন্ডো বন্ধ হওয়ার আগে ওয়ার্কারকে সংযোগ-বিচ্ছিন্নতার নোটিফিকেশন পাঠায়।
1  request<T = unknown>(action: RequestAction): Promise<T> {
2    const id = randomId();
3    return new Promise<T>((resolve, reject) => {
4      this.pending.set(id, { resolve, reject });
5      this.port.postMessage({ kind: 'request', id, from: this.clientId, action });
6    });
7  }
  • request মেথড নির্দিষ্ট অ্যাকশন ওয়ার্কারকে পাঠায় এবং ফলাফল Promise হিসেবে গ্রহণ করে।
1  ping() {
2    return this.request<string>({ type: 'ping' });
3  }
4  echo(payload: string) {
5    return this.request<string>({ type: 'echo', payload });
6  }
7  getTime() {
8    return this.request<string>({ type: 'getTime' });
9  }
  • এগুলো মৌলিক যোগাযোগ পরীক্ষা এবং বর্তমান সময় পাওয়ার জন্য ইউটিলিটি মেথড।
1  set(key: string, value: unknown) {
2    return this.request<boolean>({ type: 'set', key, value });
3  }
4  get<T = unknown>(key: string) {
5    return this.request<T>({ type: 'get', key });
6  }
  • এগুলো কী-ভ্যালু জোড়া সংরক্ষণ ও পুনরুদ্ধারের জন্য মেথড।
1  broadcast(channel: string, payload: unknown) {
2    return this.request<boolean>({ type: 'broadcast', channel, payload });
3  }
  • এটি এমন একটি মেথড যা ওয়ার্কারের মাধ্যমে অন্যান্য ক্লায়েন্টকে সম্প্রচার বার্তা পাঠায়।
1  lockAcquire(key: string, timeoutMs?: number) {
2    return this.request<{ owner: string }>({ type: 'lock.acquire', key, timeoutMs });
3  }
4  lockRelease(key: string) {
5    return this.request<boolean>({ type: 'lock.release', key });
6  }
7}
  • এগুলো এমন মেথড যা শেয়ারড রিসোর্সে মিউচুয়াল এক্সক্লুশন অর্জনের জন্য লক অধিগ্রহণ ও মুক্তি দেয়।
  • এই ফাইল জুড়ে, প্রতিটি ব্রাউজার ট্যাব থেকে Shared Worker-এ নিরাপদ, অ্যাসিঙ্ক্রোনাস যোগাযোগের জন্য একটি ক্লায়েন্ট API বাস্তবায়িত হয়েছে।

ব্যবহারের উদাহরণ

demo.ts-এ, আগেই তৈরি করা SharedWorkerClient ক্লাসটি ব্যবহার করে আমরা এর আচরণ যাচাই করি। এটি যোগাযোগ পরীক্ষা, ডেটা পড়া ও লেখা, ব্রডকাস্টিং এবং লক পরিচালনাসহ একাধিক ফাংশন ধারাবাহিকভাবে সম্পাদন করে।

 1// demo.ts
 2import { SharedWorkerClient } from './shared-worker-client.js';
 3
 4const client = new SharedWorkerClient(new URL('./shared-worker.js', import.meta.url), 'app-shared', (b) => {
 5  console.log('[BROADCAST]', b.channel, JSON.stringify(b.payload));
 6});
 7
 8async function demo() {
 9  console.log('ping:', await client.ping());
10  console.log('echo:', await client.echo('hello'));
11  console.log('time:', await client.getTime());
12
13  // Counter update
14  await client.set('counter', (await client.get<number>('counter')) ?? 0);
15  const c1 = await client.get<number>('counter');
16  await client.set('counter', (c1 ?? 0) + 1);
17  console.log('counter:', await client.get<number>('counter'));
18
19  // Broadcast test
20  await client.broadcast('notify', { msg: 'Counter updated' });
21
22  // Lock test
23  const key = 'critical';
24  console.log(`[lock] Trying to acquire lock: "${key}"`);
25  const lockResult = await client.lockAcquire(key, 2000);
26  console.log(`[lock] Lock acquired for key "${key}":`, lockResult);
27
28  try {
29    console.log(`[lock] Simulating critical section for key "${key}"...`);
30    await new Promise((r) => setTimeout(r, 250));
31    console.log(`[lock] Critical section completed for key "${key}"`);
32  } finally {
33    console.log(`[lock] Releasing lock: "${key}"`);
34    const releaseResult = await client.lockRelease(key);
35    console.log(`[lock] Lock released for key "${key}":`, releaseResult);
36  }
37}
38
39demo().catch(console.error);
  • এই কোডটি একটি ডেমো, যা একাধিক ব্রাউজার ট্যাব জুড়ে ডেটা ও স্টেট শেয়ার ও সিঙ্ক করতে Shared Worker ব্যবহার করে। বার্তা-ভিত্তিক যোগাযোগ ব্যবহার করে, আপনি শিথিল কাপলিংসহ নিরাপদে অ্যাসিঙ্ক্রোনাস বার্তা আদান-প্রদান করতে পারেন, যা ভিন্ন ভিন্ন কনটেক্সটের মধ্যে যোগাযোগ পরিচালনা করা সহজ করে। অতিরিক্তভাবে, RPC ব্যবহার করে ওয়ার্কারের সঙ্গে যোগাযোগকে একটি স্বতঃস্ফূর্ত, মেথড-কল-সদৃশ শৈলীতে বিমূর্ত করা যায়, ফলে রক্ষণাবেক্ষণযোগ্যতা ও পঠনযোগ্যতা বাড়ে।

HTML-এ টেস্ট করা

 1<!DOCTYPE html>
 2<html lang="en">
 3<head>
 4  <meta charset="UTF-8" />
 5  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 6  <title>Shared Worker Demo</title>
 7</head>
 8<body>
 9  <h1>SharedWorker Demo</h1>
10  <p>Open the browser console to see the output.</p>
11
12  <script type="module">
13    import './demo.js';
14  </script>
15</body>
16</html>

ডিজাইন ও অপারেশনাল বিবেচ্য বিষয়

ডিজাইন ও পরিচালনার সময় নিম্নলিখিত বিষয়গুলো মাথায় রাখলে আরও মজবুত ও সম্প্রসারণযোগ্য একটি সিস্টেম গড়ে তুলতে সহায়তা করবে।

  • kind বা type-এর ওপর ভিত্তি করে ব্রাঞ্চিং করতে দেয় এমন একটি discriminated union (tagged union) আপনি ব্যবহার করতে পারেন।
  • অনুরোধকে সঠিকভাবে প্রতিক্রিয়ার সঙ্গে মিলাতে একটি correlation ID ব্যবহার করুন।
  • হার্টবিট এবং স্বয়ংক্রিয় পরিষ্কার পরিত্যক্ত লক প্রতিরোধ করতে পারে।
  • ভবিষ্যতের প্রোটোকল পরিবর্তনগুলো নমনীয়ভাবে গ্রহণ করতে versioning বাস্তবায়ন করুন।
  • স্পষ্ট ত্রুটি কোড সংজ্ঞায়িত করলে UI-পার্শ্বের হ্যান্ডলিং ও ডিবাগিং সহজ হয়।

সারসংক্ষেপ

Shared Worker হল একাধিক ব্রাউজার ট্যাব জুড়ে ডেটা ও স্টেট শেয়ার করার জন্য একটি মূল প্রক্রিয়া।

এখানে উপস্থাপিত কাঠামোটি টাইপ-নিরাপদ RPC যোগাযোগ, হার্টবিটের মাধ্যমে লাইভনেস মনিটরিং, এবং একটি লকিং মেকানিজম সরবরাহ করে, যা এটিকে প্রোডাকশনে হুবহু ব্যবহারযোগ্য শক্তিশালী নকশায় পরিণত করে।

এই মেকানিজমের উপর ভিত্তি করে, আপনি নিম্নলিখিত অ্যাপ্লিকেশনগুলোও বাস্তবায়ন করতে পারেন।

  • IndexedDB অ্যাক্সেস সিরিয়ালাইজ করা
  • WebSocket সংযোগের ইন্টিগ্রেশন ও শেয়ারিং
  • একাধিক ট্যাব জুড়ে একটি জব কিউ নির্মাণ
  • থ্রোটলিং এবং প্রগ্রেস নোটিফিকেশন ডেলিভারি

আপনি যেমন দেখলেন, Shared Worker কাজে লাগিয়ে একাধিক ট্যাব জুড়ে নিরাপদ ও দক্ষতার সঙ্গে ডেটা ও প্রসেসিং শেয়ার করা সম্ভব।

আপনি আমাদের ইউটিউব চ্যানেলে ভিজ্যুয়াল স্টুডিও কোড ব্যবহার করে উপরের নিবন্ধটি অনুসরণ করতে পারেন। দয়া করে ইউটিউব চ্যানেলটিও দেখুন।

YouTube Video