প্রগতি আপডেটসহ পটভূমি কাজ: কাজ করা UI প্যাটার্নগুলো
প্রগতি আপডেটসহ পটভূমি টাস্কের জন্য ব্যবহারিক প্যাটার্ন শিখুন: কিউ, স্ট্যাটাস মডেল, UI মেসেজিং, ক্যানসেল ও রিট্রাই, এবং ত্রুটি রিপোর্টিং।

কেন ব্যবহারকারীরা আটকে পড়ে যখন কাজ পটভূমিতে চলছে
দীর্ঘ সময় নেওয়া কাজ UI ব্লক করা উচিৎ নয়। মানুষ ট্যাব বদলায়, সংযোগ হারায়, ল্যাপটপ বন্ধ করে দেয়, বা কেবল ভাবতে থাকে কিছুই হচ্ছে কি না। স্ক্রীন ফ্রোজেন হলে ব্যবহারকারী অনুমান করে আর অনুমানই বারবার ক্লিক, ডুপ্লিকেট সাবমিশন, এবং সাপোর্ট টিকিটে পরিণত হয়।
ভাল ব্যাকগ্রাউন্ড ওয়ার্ক আসলে আত্মবিশ্বাস সম্পর্কে। ব্যবহারকারীরা তিনটি জিনিস চায়:
- একটি স্পষ্ট স্ট্যাটাস (queued, running, done)
- সময়ের ধারণা (এমনকি একটা আনুমানিক অঙ্ক)
- একটি স্পষ্ট পরবর্তী অ্যাকশন (অপেক্ষা করা, কাজ চালিয়ে যাওয়া, ক্যানসেল করা, বা পরে ফিরে আসা)
এসব না থাকলে কাজ ঠিকভাবে চললেও অভিজ্ঞতা টুটে যায়।
একটি সাধারণ ভুল হল ধীর রিকোয়েস্টকে প্রকৃত পটভূমি কাজ হিসেবে বিবেচনা করা। ধীর রিকোয়েস্ট এখনও একটি ওয়েব কল যা ব্যবহারকারীকে অপেক্ষা করায়। পটভূমি কাজ আলাদা: আপনি একটি জব শুরু করেন, একটি তাৎক্ষণিক কনফার্মেশন পান, এবং ভারী প্রসেসিং অন্যত্র ঘটে যখন UI ব্যবহৃত থাকে।
উদাহরণ: ব্যবহারকারী একটি CSV আপলোড করে কাস্টমার ইম্পোর্ট করার জন্য। যদি UI ব্লক করে, তারা রিফ্রেশ করে আবার আপলোড করতে পারে এবং ডুপ্লিকেট তৈরি হতে পারে। যদি ইম্পোর্ট ব্যাকগ্রাউন্ডে শুরু হয় এবং UI একটি জব কার্ড দেখায় প্রগতি ও নিরাপদ ক্যানসেল বিকল্পের সঙ্গে, তারা কাজ চালিয়ে যেতে পারে এবং স্পষ্ট ফলাফলের জন্য ফিরে যেতে পারে।
মূল নির্মাণ ব্লক: জব, কিউ, ওয়ার্কার, এবং স্ট্যাটাস
যখন মানুষ পটভূমি টাস্ক ও প্রগতি আপডেটের কথা বলে, তারা সাধারণত চারটি অংশ নিয়ে কথা বলে।
একটি জব কাজের ইউনিট: import this CSV, generate this report, বা send 5,000 emails। একটি কিউ হল অপেক্ষার সারি যেখানে জবগুলো অপেক্ষা করে যতক্ষণ না সেগুলো প্রসেস করা যায়। একটি ওয়ার্কার কিউ থেকে জব টেনে নিয়ে কাজটি করে (একটি করে বা একাধিক সমান্তরালে)।
UI-এর জন্য সবচেয়ে গুরুত্বপূর্ণ অংশ হল জবের লাইফসাইকেল স্টেট। স্টেটগুলো কম এবং পূর্বানুমেয় রাখুন:
- Queued: গ্রহণ করা হয়েছে, ওয়ার্কার পাওয়ার অপেক্ষায়
- Running: সক্রিয়ভাবে প্রসেস করা হচ্ছে
- Done: সফলভাবে শেষ
- Failed: কোনো ত্রুটিতে বন্ধ
প্রতিটি জবের জন্য একটি জব ID (একক রেফারেন্স) থাকা জরুরি। ব্যবহারকারী যখন বাটন ক্লিক করে, সেই ID তাৎক্ষণিকভাবে ফেরত দিন এবং টাস্ক প্যানেলে একটি "Task started" সারি দেখান।
তারপর জানতে হবে, "এখন কী হচ্ছে?"—এটার জন্য সাধারণত একটি স্ট্যাটাস এন্ডপয়েন্ট (অথবা যেকোনও রিড মেথড) থাকে যা জব ID নিয়ে স্টেট এবং প্রগতি ডিটেইল ফেরত দেয়। UI এটি ব্যবহার করে শতাংশ সম্পন্ন, বর্তমান স্টেপ, এবং যেকোনো বার্তা দেখায়।
সবশেষে, স্ট্যাটাস অবশ্যই একটি টেকসই স্টোরে থাকতে হবে, কেবল মেমরিতে নয়। ওয়ার্কার ক্র্যাশ করে, অ্যাপ রিস্টার্ট হয়, এবং ব্যবহারকারী পেজ রিফ্রেশ করে—টেকসই স্টোরই প্রগতি এবং আউটকামকে নির্ভরযোগ্য করে। কমপক্ষে সংরক্ষণ করুন:
- বর্তমান স্টেট এবং টাইমস্ট্যাম্প
- প্রগতি মান (শতাংশ বা কাউন্ট)
- ফলাফল সারসংক্ষেপ (কি তৈরি বা পরিবর্তিত হয়েছে)
- ত্রুটি বিবরণ (ডিবাগ ও ব্যবহারকারীর জন্য)
যদি আপনি AppMaster-এর মতো প্ল্যাটফর্মে নির্মাণ করেন, স্ট্যাটাস স্টোরকে অন্য ডেটা মডেলের মতো扱ব্যবহার করুন: UI জব ID দিয়ে সেটি পড়ে, আর ওয়ার্কার কাজের সময় সেটি আপডেট করে।
আপনার ওয়ার্কলোডের সাথে মিল রেখে কিউ প্যাটার্ন বেছে নেওয়া
আপনি যে কিউ প্যাটার্ন বেছে নেবেন তা অ্যাপকে কতটা 'ন্যায়সঙ্গত' এবং পূর্বানুমেয় করবে তা বদলে দেয়। যদি একটি টাস্ক বহু কাজের পিছনে আটকে থাকে, ব্যবহারকারী এটি র্যান্ডম দেরি হিসেবে অনুভব করবে, এমনকি সিস্টেম ঠিকঠাক থাকলেও। তাই কিউ নির্বাচনের সিদ্ধান্ত শুধুই ইনফ্রা নয়—এটি UX সিদ্ধান্তও।
কম ভলিউম, ছোট জব, এবং সাময়িক রিট্রাই সহ্য করা যায় এমন পরিস্থিতিতে একটি সাদাসিধে ডাটাবেস-ব্যাকড কিউই যথেষ্ট হতে পারে। সেটআপ সহজ, ইন্সপেকশন সহজ, এবং সবকিছু এক জায়গায় রাখা যায়। উদাহরণ: একটি অ্যাডমিন রাত্রীকালে ছোট টিমের জন্য রিপোর্ট চালায়—একবার রিট্রাই হলে কেউ প্যানিক করে না।
যখন থ্রুপুট বাড়ে, জব ভারী হয়, বা নির্ভরযোগ্যতা অপরিহার্য হয়ে ওঠে, তখন ডেডিকেটেড কিউ সিস্টেম দরকার। ইম্পোর্ট, ভিডিও প্রসেসিং, ভরসামরিক নোটিফিকেশন, এবং যেকোনও ওয়ার্কফ্লো যা রিস্টার্ট জুড়ে চলতে হবে সেগুলো আলাদা কিউ থেকে সুবিধা পায়: বিচ্ছিন্নতা, দৃশ্যমানতা, এবং নিরাপদ রিট্রাই আচরণ। এটি ব্যবহারকারীর মুখে দেখা প্রগতির জন্য গুরুত্বপূর্ণ কারণ মানুষ মিসিং আপডেট ও আটকে থাকা স্টেট লক্ষ্য করে।
কিউ স্ট্রাকচারও অগ্রাধিকারকে প্রভাবিত করে। একটিমাত্র কিউ সহজ, কিন্তু দ্রুত এবং ধীর কাজ মিশিয়ে দিলে দ্রুত অ্যাকশনগুলো ধীর মনে হবে। আলাদা কিউ সাহায্য করে যখন ব্যবহারকারী-উদ্দীপিত কাজ দ্রুত হওয়া উচিত আর নির্ধারিত ব্যাচ কাজ অপেক্ষা করতে পারে।
উদ্দেশ্যপ্রণোদিতভাবে কনকারেন্সি লিমিট সেট করুন। অনেক পারালালিজম আপনার ডাটাবেসকে ওভারলোড করতে পারে এবং প্রগতি ঝাঁপটা মনে করাতে পারে; খুব কম হলে সিস্টেম স্নাগিং মনে হবে। প্রতিটি কিউয়ের জন্য ছোট, পূর্বানুমেয় কনকারেন্সি দিয়ে শুরু করুন, তারপর কেবল যখন আপনি সমাপ্তির সময় স্থিতিশীল রাখতে পারেন তখন বাড়ান।
এমন একটি প্রগতি মডেল ডিজাইন করা যা UI-এ দেখানো যায়
যদি আপনার প্রগতি মডেল অস্পষ্ট, UI-ও অস্পষ্ট হবে। সিস্টেম কি সত্যিই রিপোর্ট করতে পারবে, কত ঘনই পরিবর্তন হবে, এবং ব্যবহারকারী ঐ তথ্য নিয়ে কি করবে তা নির্ধারণ করুন।
একটি সরল স্ট্যাটাস স্কিমা যা বেশিরভাগ জব সাপোর্ট করতে পারে:
- state: queued, running, succeeded, failed, canceled
- percent: 0-100 যখন আপনি এটি মাপতে পারেন
- message: ব্যবহারকারীর বোঝার জন্য এক বাক্য
- timestamps: created, started, last_updated, finished
- result_summary: processed, skipped, errors-এর মতো কাউন্ট
পরবর্তীভাবে, নির্ধারণ করুন "প্রগতি" মানে কি।
শতাংশ তখনই কাজ করে যখন বাস্তব ডিনোমিনেটর থাকে (ফাইলে সারি, ইমেইলের সংখ্যা)। যখন কাজ অনিশ্চিত (তৃতীয় পক্ষের অপেক্ষা, ভেরিয়েবল কম্পিউট, বা ব্যয়বহুল কুয়েরি) তখন এটি মিথ্যা অনুধাবন দেয়। সেই ক্ষেত্রে ধাপ-ভিত্তিক প্রগতি আরো বিশ্বাসযোগ্য কারণ এটি পরিষ্কার ব্লকগুলোতে এগোয়।
একটি ব্যবহারিক নিয়ম:
- যখন আপনি প্রকৃতভাবে "X of Y" রিপোর্ট করতে পারেন তখন percent ব্যবহার করুন।
- সময় অনিশ্চিত হলে steps ব্যবহার করুন (Validate file, Import, Rebuild indexes, Finalize)।
- যদি দুটোই না হয়, indeterminate প্রগতি ব্যবহার করুন, কিন্তু বার্তা সতেজ রাখুন।
জব চলাকালীন আংশিক ফলাফল সংরক্ষণ করুন। এতে UI কাজ শেষ হওয়ার আগে কিছু ব্যবহারযোগ্য দেখাতে পারে, যেমন লাইভ ত্রুটি কাউন্ট বা কি পরিবর্তন হয়েছে তার প্রিভিউ। CSV ইম্পোর্টে আপনি rows_read, rows_created, rows_updated, rows_rejected এবং শেষ কয়েকটি ত্রুটি বার্তা সংরক্ষণ করতে পারেন।
এটাই সেই ভিত্তি যা ব্যবহারকারীদের বিশ্বাসযোগ্য ব্যাকগ্রাউন্ড টাস্ক দিয়ে দেয়: UI শান্ত থাকে, সংখ্যাগুলো চলছে, এবং কাজ শেষ হলে "কি ঘটেছিল?" সারসংক্ষেপ প্রস্তুত থাকে।
প্রগতি আপডেট ডেলিভারি: পোলিং, পুশ, এবং হাইব্রিড
ব্যাকএন্ড থেকে পর্দায় প্রগতি আনা সেই জায়গা যেখানে অনেক বাস্তবায়ন ভেঙে পড়ে। এমন একটি ডেলিভারি পদ্ধতি বেছে নিন যা কতবার প্রগতি পরিবর্তিত হয় এবং কতজন ব্যবহারকারী এটাতে নজর রাখবে তার সাথে মানায়।
পোলিং সহজ: UI প্রতিটি N সেকেন্ডে স্ট্যাটাস জিজ্ঞাসা করে। ভাল ডিফল্ট হচ্ছে ব্যবহারকারী সক্রিয়ভাবে পেজ দেখলে 2-5 সেকেন্ড; জব এক মিনিটের বেশি চললে 10-30 সেকেন্ডে নেমে যান। ট্যাব ব্যাকগ্রাউন্ডে থাকলে আরো ধীর করুন।
পুশ আপডেট (WebSockets, server-sent events, বা মোবাইল নোটিফিকেশন) তখন উপকারি যখন প্রগতি দ্রুত পরিবর্তিত হয় বা ব্যবহারকারী "এখনই" জানতে চায়। পুশ তাত্ক্ষণিকতা দেয়, কিন্তু সংযোগ ছিন্ন হলে একটি ফোলব্যাক থাকতে হবে।
একটি হাইব্রিড অ্যাপ্রোচ প্রায়শই সেরা: শুরুতে দ্রুত পোলিং করুন (তাতে UI দ্রুত দেখতে পায় queued থেকে running), তারপর জব স্থির হলে ধীর হয়ে যান। যদি আপনি পুশ যোগ করেন, একটি ধীর পোলিং সেফটি নেট হিসেবে রাখুন।
আপডেট বন্ধ হয়ে গেলে এটাকে প্রথম শ্রেণির স্টেট হিসেবে বিবেচনা করুন। "Last updated 2 minutes ago" দেখান এবং রিফ্রেশ অফার করুন। ব্যাকএন্ডে, হার্টবিট না এলে জবকে স্টেইল হিসেবে চিহ্নিত করুন।
দীর্ঘ চলা টাস্কের জন্য UI প্যাটার্ন যা স্পষ্ট লাগে
স্পষ্টতা দুই জিনিস থেকে আসে: একটি ছোট সেট পূর্বানুমেয় স্টেট, এবং এমন কপি যা মানুষকে বলে পরবর্তী কি হবে।
UI-তে স্টেটগুলোর নাম দিন, কেবল ব্যাকএন্ডে নয়। একটি জব queued (এটির পাল ধরার অপেক্ষায়), running (কাজ করছে), waiting for input (নির্বাচন দরকার), completed, completed with errors, বা failed হতে পারে। যদি ব্যবহারকারীরা এগুলো আলাদা করতে না পারে, তারা ভাববে অ্যাপ আটকে গেছে।
প্রগতি নির্দেশকের পাশে সাধারণ, ব্যবহারযোগ্য কপি ব্যবহার করুন। "Importing 3,200 rows (1,140 processed)" এর চেয়ে "Processing." কম তথ্যবহুল। একটি এক বাক্যের বার্তা যোগ করুন যা বলে: আমি কি যেতে পারি, এবং কি হবে? যেমন: "আপনি এই উইন্ডো বন্ধ করতে পারবেন। আমরা ব্যাকগ্রাউন্ডে ইম্পোর্ট চালিয়ে রাখব এবং প্রস্তুত হলে আপনাকে জানাব।"
প্রগতি যেখানে থাকবে তা ব্যবহারকারীর প্রসঙ্গের সাথে মিলানো উচিত:
- যদি টাস্ক পরবর্তী ধাপকে ব্লক করে (যেমন সেই ইনভয়েস PDF তৈরির দরকার যা এখনই দরকার), তখন একটি মডাল কাজ করে।
- দ্রুত টাস্কের জন্য যা বিঘ্নিত করা উচিত নয়, একটি টোস্ট ভাল।
- প্রতিটি আইটেম অপারেশনের জন্য টেবিল রো-র মধ্যে ইনলাইন প্রগতি ভাল।
এক মিনিটের বেশি কিছু হলে একটি সিম্পল Jobs পেজ বা Activity প্যানেল যোগ করুন যাতে মানুষ পরে কাজ খুঁজে পায়।
একটি স্পষ্ট দীর্ঘ-চলা টাস্ক UI সাধারণত অন্তর্ভুক্ত করে: সর্বশেষ আপডেট সময়সহ স্ট্যাটাস লেবেল, একটি প্রগতি বার (অথবা ধাপ) এবং এক লাইনের বিস্তারিত, নিরাপদ ক্যানসেল আচরণ, এবং সারাংশ ও পরবর্তী অ্যাকশন সহ একটি ফলাফল এলাকা। সম্পন্ন জবগুলোকে সহজেই অন্বেষণযোগ্য রাখুন যাতে ব্যবহারকারী এক স্ক্রীনে আটকে না পড়ে।
ত্রুটিসহ শেষ হওয়া রিপোর্ট করা যাতে ব্যবহারকারী বিভ্রান্ত হন না
"Finished" সবসময় একটি পূর্ণ বিজয় নয়। যখন একটি ব্যাকগ্রাউন্ড জব 9,500 রেকর্ড প্রসেস করে এবং 120 ব্যর্থ হয়, ব্যবহারকারীরা ঝলকঝলক লগ পড়া ছাড়া বুঝতে চায় কি ঘটেছে।
আংশিক সফলতাকে প্রথম শ্রেণির আউটকাম হিসেবে বিবেচনা করুন। প্রধান স্ট্যাটাস লাইনে উভয় দিক দেখান: "Imported 9,380 of 9,500. 120 failed." এটি বিশ্বাস রাখে কারণ সিস্টেম সৎ, এবং নিশ্চিত করে কাজ সংরক্ষিত হয়েছে।
তারপর একটি ছোট ত্রুটি সারসংক্ষেপ দেখান যা ব্যবহারকারী কার্যকর পদক্ষেপ নিতে পারে: "Missing required field (63)" এবং "Invalid date format (41)"। চূড়ান্ত স্টেটে "Completed with issues" প্রায়ই "Failed" থেকে পরিষ্কার কারণ তা পুরো কাজ বাতিল হয়েছে বলে অর্থ দেয় না।
একটি এক্সপোর্টেবল ত্রুটি রিপোর্ট বিভ্রান্তিকে একটি টু-ডু তালিকায় পরিণত করে। সরল রাখুন: সারি বা আইটেম আইডেন্টিফায়ার, ত্রুটি ক্যাটেগরি, একটি মানব-বোধগম্য বার্তা, এবং প্রাসঙ্গিক ক্ষেত্রের নাম।
পরবর্তী অ্যাকশন সহজে খুঁজে পাওয়া যায় এমন করে রাখুন: ডেটা ঠিক করে ব্যর্থ আইটেমগুলো পুনরায় চেষ্টা করুন, ত্রুটি রিপোর্ট ডাউনলোড করুন, অথবা সিস্টেম সমস্যা হলে সাপোর্টে যোগাযোগ করুন—সঙ্গে জব আইডি দিন।
ব্যবহারকারী বিশ্বাসযোগ্য এমন ক্যানসেল ও রিট্রাই অ্যাকশন
ক্যানসেল এবং রিট্রাই সহজ মনে হলেও দ্রুত বিশ্বাস ভাঙায় যখন UI এক কথা বলে আর সিস্টেম অন্য কিছু করে। প্রতিটি জব টাইপের জন্য ক্যানসেল কী বোঝায় তা সংজ্ঞায়িত করুন, তারপর UI-তেও তা সৎভাবে প্রতিফলিত করুন।
সাধারণত দুই ধরনের ক্যানসেল মোড আছে:
- "Stop now": ওয়ার্কার প্রায়ই ক্যানসেল ফ্ল্যাগ চেক করে এবং দ্রুত বেরিয়ে যায়।
- "Stop after this step": বর্তমান স্টেপ সম্পন্ন হয়, তারপর পরবর্তী স্টেপ শুরুর আগে জব বন্ধ করে দেয়া হয়।
UI-তে একটি মধ্যবর্তী স্টেট দেখান যেমন "Cancel requested" যাতে ব্যবহারকারী বারবার ক্লিক না করে।
ক্যানসেল নিরাপদ করতে কাজটি পুনরায় চালানো যোগ্য করে ডিজাইন করুন। যদি জব ডেটা লিখে, আইডেমপটেন্ট অপারেশন ব্যবহার করুন (দুইবার চালালে ক্ষতি না হয়) এবং যেখানে দরকার ক্লিনআপ করুন। উদাহরণস্বরূপ, CSV ইম্পোর্ট রেকর্ড তৈরি করলে job-run ID সংরক্ষণ করুন যাতে আপনি run #123-এ কি পরিবর্তন হয়েছে তা পর্যালোচনা করতে পারেন।
রিট্রাই-ও একই স্পষ্টতা চাই। একই জব ইন্সট্যান্স রিসিউম করার সময়িৎবোধ করা যায় যদি এটি রিসিউম করতে পারে। নতুন জব ইন্সট্যান্স তৈরি করা নিরাপদ যখন আপনি একটি পরিষ্কার রান চান নতুন টাইমস্ট্যাম্প এবং অডিট ট্রেইলের সঙ্গে। যাই হোক, ব্যবহারকারীকে বুঝিয়ে বলুন কি হবে এবং কি হবে না।
কয়েকটি গার্ডরেইল যা ক্যানসেল ও রিট্রাইকে পূর্বানুমেয় রাখে:
- রিট্রাই সীমা রাখুন এবং কাউন্ট দেখান।
- একটি জব চলাকালীন রিট্রাই নিষিদ্ধ করে ডুব্লিকেট রান থামান।
- রিট্রাই ডুপ্লিকেট সাইড ইফেক্ট (ইমেইল, পেমেন্ট, এক্সপোর্ট) তৈরি করতে পারে এমন হলে কনফার্ম চান।
- ডিটেইল প্যানেলে শেষ ত্রুটি এবং শেষ সফল স্টেপ দেখান।
ধাপে ধাপে: ক্লিক থেকে সমাপ্তি পর্যন্ত একটি এন্ড-টু-এন্ড ফ্লো
ভালো এন্ড-টু-এন্ড ফ্লো একটি নিয়ম দিয়ে শুরু করে: UI কখনই কাজের জন্য অপেক্ষা করবেনা; কেবল জব ID-র জন্য অপেক্ষা করবে।
ফ্লো (ব্যবহারকারী ক্লিক থেকে চূড়ান্ত স্টেটে)
-
ব্যবহারকারী টাস্ক শুরু করে, API দ্রুত রিটার্ন করে। ব্যবহারকারী Import বা Generate report ক্লিক করলে সার্ভার তাৎক্ষণিকভাবে একটি জব রেকর্ড তৈরি করে এবং একটি ইউনিক জব ID দেয়।
-
কাজ কিউতে ঢোকান এবং প্রথম স্ট্যাটাস সেট করুন। জব ID কিউতে রাখুন এবং স্ট্যাটাস queued ও প্রগতি 0% সেট করুন—এটা UI-কে কিছু বাস্তব দেখানোর সুযোগ দেয় ওয়ার্কার পিক আপ করার আগে।
-
ওয়ার্কার রান করে এবং প্রগতি রিপোর্ট করে। ওয়ার্কার শুরু হলে স্ট্যাটাস running সেট করুন, স্টার্ট টাইম স্টোর করুন, এবং ছোট, সৎ আপডেটে প্রগতি বাড়ান। যদি শতাংশ মাপা না যায়, Parsing, Validating, Saving-এর মতো স্টেপ দেখান।
-
UI ব্যবহারকারীকে দিকনির্দেশ দেয়। UI পোল বা সাবস্ক্রাইব করে আপডেট নিয়ে রেন্ডার করে স্পষ্ট স্টেট দেখায়। সংক্ষিপ্ত বার্তা দেখান (এখন কি হচ্ছে) এবং কেবল সেই অ্যাকশনগুলো দেখান যা এখন অর্থপূর্ণ।
-
টেকসই ফলাফলের সঙ্গে চূড়ান্ত করুন। সম্পন্ন হলে ফিনিশ টাইম, আউটপুট (ডাউনলোড রেফারেন্স, তৈরি আইডি, সারসংক্ষেপ কাউন্ট), এবং ত্রুটি বিবরণ সংরক্ষণ করুন। finished-with-errors-কে একটি আলাদা আউটকাম হিসেবে হ্যান্ডেল করুন, অস্পষ্ট সাফল্য নয়।
ক্যানসেল ও রিট্রাই নিয়ম
ক্যানসেল স্পষ্ট হওয়া উচিত: ক্যানসেল রিকুয়েস্ট পাঠানো হলে ওয়ার্কার তা গ্রহণ করে এবং ক্যানসেলড মার্ক করে। রিট্রাই একটি নতুন জব ID তৈরি করা উচিত, মূলটি হিস্ট্রিরূপে রেখে, এবং ব্যাখ্যা করুন কি আবার চলবে।
উদাহরণ দৃশ্য: প্রগতি ও আংশিক ব্যর্থতা সহ CSV ইম্পোর্ট
CSV ইম্পোর্ট এমন একটি জায়গা যেখানে পটভূমি টাস্ক ও প্রগতি আপডেট গুরুত্বপূর্ণ। ভাবুন একটি CRM-এ sales ops ব্যক্তি customers.csv (8,420 সারি) আপলোড করে।
আপলোডের পর UI-কে অবিলম্বে বদলাতে হবে "আমি একটি বাটন ক্লিক করেছি" থেকে "একটি জব আছে, আপনি চলে যেতে পারেন"—একটি সহজ জব কার্ড Imports পেজে ভালো কাজ করে:
- Upload received: File uploaded. Validating columns...
- Queued: Waiting for an available worker (2 jobs ahead).
- Running: Importing customers: 3,180 of 8,420 processed (38%).
- Wrapping up: Saving results and building a report...
রানে একটি নির্ভরযোগ্য প্রগ্রেস নং দেখান (প্রসেস করা সারি) এবং একটি সংক্ষিপ্ত স্ট্যাটাস লাইন (এখন কি করছে)। ব্যবহারকারী ইত্যাদি নেভিগেট করলে Recent jobs এলাকায় জবটি দৃশ্যমান রাখুন।
এখন আংশিক ব্যর্থতা যোগ করুন। কাজ শেষ হলে যদি বেশিরভাগ সারি ঠিক থাকে তাহলে ভয়ানক Failed ব্যানার দেখাবেন না। Finished with issues এবং একটি স্পষ্ট বিভাজন দেখান:
Imported 8,102 customers. Skipped 318 rows.
শীর্ষ কারণগুলো সহজ ভাষায় ব্যাখ্যা করুন: invalid email format, missing required fields like company, অথবা duplicate external IDs. ব্যবহারকারীকে একটি ত্রুটি টেবিল ডাউনলোড বা দেখার সুযোগ দিন যেখানে সারি নম্বর, কাস্টমার নাম, এবং সংশ্লিষ্ট ফিল্ড দেখানো আছে।
রিট্রাই নিরাপদ ও স্পষ্ট হওয়া উচিত। মূল অ্যাকশন হতে পারে Retry failed rows, একটি নতুন জব তৈরি করবে যা কেবল 318 স্কিপ করা সারিগুলো পুনরায় প্রসেস করবে যখন ব্যবহারকারী CSV ঠিক করবে। মূল জবটি read-only রাখুন যাতে ইতিহাস সৎ থাকে।
শেষে, ফলাফল পরে সহজে খুঁজে পাওয়া যায় এমন করুন। প্রতিটি ইম্পোর্টে স্থায়ী সারসংক্ষেপ থাকা উচিত: কে চালাল, কখন, ফাইল নাম, কাউন্ট (imported, skipped), এবং ত্রুটি রিপোর্ট খোলার উপায়।
বিভ্রান্ত প্রগতি ও রিট্রাইয়ের সাধারণ ভুলগুলো
বিশ্বাস হারানোর দ্রুততম পথ হল অসত্য সংখ্যা দেখানো। 0% দুই মিনিট স্থির থাকার পরে 90% এ লাফ দেয়—এটি অনুমানের মতো লাগে। যদি আপনি সত্যিকার শতাংশ না জানেন, স্টেপ(Queued, Processing, Finalizing) দেখান বা "X of Y items processed" ব্যবহার করুন।
আরেকটি সাধারণ সমস্যা হল প্রগতি কেবল মেমরিতে সংরক্ষণ করা। ওয়ার্কার রিস্টার্ট হলে UI জব "ভুলে যায়" বা প্রগতি রিসেট হয়। জব স্টেট টেকসই স্টোরে সেভ করুন এবং UI সেই একক সোর্স থেকে পড়ুক।
রিট্রাই UX তখনই ভেঙে যায় যখন ব্যবহারকারী একই কাজ বারবার শুরু করতে পারে। যদি Import CSV বোতামটি সক্রিয় থাকে, কেউ দুইবার ক্লিক করে ডুপ্লিকেট তৈরি করবে। তারপর কোন রানটা ঠিক করতে হবে স্পষ্ট হবে না।
বারবার দেখার মতো ভুলগুলো:
- বাস্তব কাজের সাথে মেলে না এমন নমুনা শতাংশ
- প্রযুক্তিগত ত্রুটি ডাম্প ব্যবহারকারীর সামনে দেখানো (স্ট্যাক ট্রেস, কোড)
- টাইমআউট, ডুপ্লিকেট, বা আইডেমপটেন্সির জন্য হ্যান্ডলিং নেই
- রিট্রাই নতুন জব তৈরি করে কিন্তু কি হবে তা ব্যাখ্যা করে না
- ক্যানসেল কেবল UI পরিবর্তন করে, ওয়ার্কার আচরণে না
একটি ছোট কিন্তু গুরুত্বপূর্ণ বিষয়: ব্যবহারকারী বার্তা এবং ডেভেলপার বিস্তারিত আলাদা রাখুন। ব্যবহারকারীকে দেখান "12 rows failed validation" এবং প্রযুক্তিগত ট্রেস লগে রাখুন।
মুক্ত করার আগে একটি দ্রুত চেকলিস্ট
রিলিজের আগে ব্যবহারকারী যে অংশগুলো লক্ষ্য করবে সেগুলো দ্রুত পরীক্ষা করুন: স্পষ্টতা, বিশ্বাস, এবং পুনরুদ্ধার।
প্রতিটি জব এমন একটি স্ন্যাপশট প্রকাশ করা উচিত যা আপনি যেকোন জায়গায় দেখাতে পারেন: state (queued, running, succeeded, failed, canceled), progress (0-100 বা ধাপ), একটি সংক্ষিপ্ত বার্তা, টাইমস্ট্যাম্প (created, started, finished), এবং একটি result pointer (আউটপুট বা রিপোর্ট কোথায়)।
UI স্টেটগুলো স্পষ্ট ও ধারাবাহিক রাখুন। ব্যবহারকারীরা একটি স্থায়ী জায়গা চাই যেখানে বর্তমান ও পুরানো জবগুলো মিলবে, ও পরে ফিরে এলে স্পষ্ট লেবেল দেখাবে ("Completed yesterday", "Still running")। একটি Recent jobs প্যানেল প্রায়শই পুনরায় ক্লিক ও ডুপ্লিকেট কাজ প্রতিরোধ করে।
প্রতি জবের জন্য ক্যানসেল ও রিট্রাই নিয়ম সরল ভাষায় নির্ধারণ করুন। ক্যানসেল প্রতিটি জব টাইপে কি অর্থ রাখে, রিট্রাই অনুমোদিত কি না, এবং কি পুন:ব্যবহৃত হবে (একই ইনপুট, নতুন জব ID) তা ঠিক করুন। তারপর এজ কেসগুলো পরীক্ষা করুন যেমন শেষ মূহুর্তে ক্যানসেল।
আংশিক ব্যর্থতাকে একটি বাস্তব আউটকাম হিসেবে দেখুন। একটি সংক্ষিপ্ত সারাংশ দেখান ("Imported 97, skipped 3") এবং একটি কার্যকর রিপোর্ট দিন যাতে ব্যবহারকারী অবিলম্বে সমস্যা সমাধান করতে পারে।
পুনরুদ্ধারের পরিকল্পনা করুন। জবগুলো রিস্টার্ট টিকে টিকে থাকা উচিত, এবং আটকে থাকা জবগুলো টাইমআউট হয়ে একটি স্পষ্ট স্টেটে চলে যেতে উচিত যাতে নির্দেশ দেওয়া যায় ("Try again" বা "Contact support with job ID")।
পরবর্তী ধাপ: একটি ওয়ার্কফ্লো বাস্তবায়ন করে বিস্তার করা
একটি ওয়ার্কফ্লো বেছে নিন যার জন্য ব্যবহারকারীরা ইতিমধ্যেই অভিযোগ করেন: CSV ইম্পোর্ট, রিপোর্ট এক্সপোর্ট, বাল্ক ইমেইল প্রেরণ, বা ইমেজ প্রসেসিং। ছোট থেকে শুরু করুন এবং বেসিকগুলো প্রমাণ করুন: একটি জব তৈরি হয়, এটি চলে, স্ট্যাটাস রিপোর্ট করে, এবং ব্যবহারকারী পরে এটি খুঁজে পায়।
একটি সহজ জব ইতিহাস স্ক্রিন প্রায়ই সবচেয়ে বড় গুণগত উন্নতি। এটি মানুষের কাছে ফিরে যাওয়ার একটি জায়গা দেয়, স্পিনারে চেয়ে না দেখে।
প্রথমে একটি প্রগতি ডেলিভারি পদ্ধতি নির্বাচন করুন। প্রথম সংস্করণের জন্য পোলিং ঠিক আছে। রিফ্রেশ ইন্টারভাল ব্যাকএন্ডের প্রতি করুনাময় হবে কিন্তু যথেষ্ট দ্রুত হওয়া উচিত যেন জীবন্ত মনে হয়।
রাইডম্যাপ যা পুনর্লিখন এড়াচ্ছে:
- প্রথমে জব স্টেট ও ট্রানজিশন বাস্তবায়ন করুন (queued, running, succeeded, failed, finished-with-errors)
- একটি জব ইতিহাস স্ক্রিন যোগ করুন বেসিক ফিল্টার সহ (গত 24 ঘণ্টা, শুধু আমার জব)
- শুধুমাত্র আপনি সত্ রাখতে পারলে প্রগতি নাম্বার যোগ করুন
- ক্যানসেল যোগ করুন কেবল নিশ্চিত consistent ক্লিনআপ করা যাবে তখন
- রিট্রাই যোগ করুন কেবল যখন জব আইডেমপটেন্ট বা নিরাপদভাবে পুনরায় চালানো যায়
যদি আপনি কোড না লিখেই এটি তৈরি করছেন, AppMaster-এর মতো একটি নো-কোড প্ল্যাটফর্ম সাহায্য করতে পারে: একটি জব স্ট্যাটাস টেবিল (PostgreSQL) মডেল করা, ওয়ারফ্লো থেকে সেটি আপডেট করা, এবং তারপর ওয়েব ও মোবাইল UI-তে ঐ স্ট্যাটাস রেন্ডার করা। টিমগুলোর জন্য যারা ব্যাকএন্ড, UI, এবং ব্যাকগ্রাউন্ড লজিক এক জায়গায় তৈরি করতে চায়, AppMaster (appmaster.io) পুরো অ্যাপ্লিকেশন তৈরির জন্য ডিজাইন করা হয়েছে, শুধু ফর্ম বা পেজ নয়।
প্রশ্নোত্তর
একটি ব্যাকগ্রাউন্ড জব দ্রুত শুরু হয় এবং তৎক্ষণাৎ একটি জব আইডি দেয়, ফলে UI ব্যবহার যোগ্য থাকে। একটি ধীর রিকোয়েস্ট একই ওয়েব কল শেষ হওয়া পর্যন্ত ব্যবহারকারীকে অপেক্ষা করায়, যা রিফ্রেশ, ডাবল-ক্লিক এবং ডুপ্লিকেট সাবমিশনের দিকে নিয়ে যায়।
সহজ রাখুন: queued, running, done, এবং failed দেখান, আর যদি ক্যানসেল সাপোর্ট করে থাকেন তাহলে canceled যোগ করুন। অধিকাংশ কাজ সফল হলেও কিছু ব্যর্থ হলে আলাদা আউটকাম হিসেবে “done with issues” দেখানো ভাল, যাতে ব্যবহারকারী ভাবেন না সব কিছু হারিয়ে গেছে।
ব্যবহারকারী কাজ শুরু করলে দ্রুত একটি ইউনিক জব আইডি রিটার্ন করুন, তারপর ঐ আইডি দিয়ে একটি টাস্ক রো বা কার্ড রেন্ডার করুন। UI-কে জব আইডি দিয়ে স্ট্যাটাস পড়তে দিন যাতে পেজ রিফ্রেশ, ট্যাব বদলানো বা পরে ফিরে আসা যায়।
জব স্ট্যাটাস ডাটাবেজের মতো টেকসই স্টোরে সংরক্ষণ করুন, কেবল মেমরিতে নয়। বর্তমান স্টেট, টাইমস্ট্যাম্প, প্রগতি মান, একটি সংক্ষিপ্ত ব্যবহারকারী বার্তা, এবং ফলাফল বা ত্রুটি সারসংক্ষেপ সেভ করুন যাতে রিস্টার্টের পরে UI একই ভিউ পুনর্নির্মাণ করতে পারে।
শুধু তখনই পেরসেন্ট ব্যবহার করুন যখন আপনি সৎভাবে “X of Y” রিপোর্ট করতে পারেন। যদি বাস্তব ডিনোমিনেটর না থাকে, তাহলে ধাপ-ভিত্তিক প্রগতি দেখান যেমন Validating, Importing, Finalizing এবং বার্তা আপডেট রাখুন যাতে ব্যবহারকারী এগোচ্ছে বলে অনুভব করে।
পোলিং সবচেয়ে সহজ এবং বেশিরভাগ অ্যাপে ভালো কাজ করে; ব্যবহারকারী দেখার সময় 2–5 সেকেন্ডে একবার শুরু করুন, তারপর দীর্ঘ রান বা ব্যাকগ্রাউন্ড ট্যাব হলে ধীর করুন। পুশ দ্রুততা দেয়, কিন্তু সংযোগ পড়ে গেলে একটি ফোলব্যাক থাকা দরকার।
আপডেট বন্ধ হয়ে গেলে তা স্টেইল হিসেবে দেখান, ভান করে অ্যাক্টিভ দেখাবেন না — উদাহরণস্বরূপ “Last updated 2 minutes ago” দেখান এবং ম্যানুয়াল রিফ্রেশ অফার করুন। ব্যাকএন্ডে হার্টবিট না এলে জবকে স্টেইল হিসেবে চিহ্নিত করুন এবং নির্দেশ দিন, যেমন আবার চেষ্টা করুন বা জব আইডি নিয়ে সাপোর্টে যোগাযোগ করুন।
পরবর্তী অ্যাকশনটি স্পষ্ট করুন: ব্যবহারকারী কাজ চালিয়ে যেতে পারবে, পেজ ছেড়ে যেতে পারবে, বা নিরাপদে ক্যানসেল করতে পারবে কি না। এক মিনিটের বেশি লম্বা টাস্ক হলে একটি নির্দিষ্ট Jobs বা Activity ভিউ দিন যাতে ব্যবহারকারী পরে ফলাফল খুঁজে পায়।
এটাকে একটি বৈধ আউটকাম হিসেবে দেখান এবং উভয় দিক স্পষ্টভাবে বলুন, যেমন “Imported 9,380 of 9,500. 120 failed.” তারপর একটি সংক্ষিপ্ত, কার্যকর ত্রুটি সারসংক্ষেপ দিন যাতে ব্যবহারকারী লগ না পড়ে সমস্যা ঠিক করতে পারে। প্রযুক্তিগত বিস্তারিত অভ্যন্তরীণ লগে রাখুন।
প্রতিটি জবের জন্য ক্যানসেল কী মানে তা নির্ধারণ করুন এবং UI-তে সৎভাবে প্রতিফলিত করুন; একটি মধ্যবর্তী স্টেট দেখান যেমন “cancel requested” যাতে ব্যবহারকারী বারবার ক্লিক না করে। কাজকে আইডেমপটেন্ট তৈরির চেষ্টা করুন, রিট্রাই সীমাবদ্ধ রাখুন, এবং ঠিক করুন রিট্রাই একই জব রিসিউম করবে না কি নতুন আইডি তৈরী করবে।


