ঘুম থেকে জাগলে ভাঙে যে অ্যাপ — Windows পাওয়ার ইভেন্টের কাজ ও যে ব্যবসায়িক অ্যাপ তা সহ্য করে

· · Windows, পাওয়ার ম্যানেজমেন্ট, Windows ডেভেলপমেন্ট, ব্যবসায়িক অ্যাপ, ডিভাইস নিয়ন্ত্রণ, সমস্যা সমাধান, Win32 API

“ল্যাপটপ বন্ধ করলাম, পরদিন সকালে খুললাম, ব্যবসায়িক অ্যাপ ত্রুটিতে ভরা।” “যন্ত্র-নিরীক্ষণ অ্যাপ শুধু দুপুরের পর ডেটা ফেলে দেয়।” “Excel-এ রপ্তানি করা রেসিডেন্ট টুল মাঝে মাঝে সংযোগ ত্রুটিতে থেমে যায়।” — এই টিকিটগুলোর সন্দেহভাজন একটাই। ঘুম

ডেস্কটপ PC যখন মূলধারা ছিল সেই যুগের ব্যবসায়িক অ্যাপ লেখা হয়েছিল “PC চালুই থাকে” এই অব্যক্ত ধারণায়। আজকের মূল যুদ্ধক্ষেত্র ল্যাপটপ, আর ডিফল্টে কয়েক মিনিট আইডলের পর ঘুমায়। Modern Standby-সক্ষম মেশিনে ঘুমের অর্থই ঐতিহ্যবাহী মডেল থেকে বদলে গেছে। Windows-এ ব্যবসায়িক অ্যাপ ও যন্ত্র-নিয়ন্ত্রণ সফটওয়্যার লেখা ডেভেলপারদের লক্ষ্য করে এই নিবন্ধ প্রাথমিক উৎস থেকে সাজায় OS ঘুমের আগে-পরে অ্যাপকে কী জানায়, কী ভাঙে, আর জাগরণ সহ্য করে এমন অ্যাপ কীভাবে লিখবেন।

১. আগে উপসংহার

  • ঘুম এমন ইভেন্ট যা অ্যাপের “প্রত্যাখ্যান করার অধিকার নেই”। ঠিক আগে WM_POWERBROADCAST (PBT_APMSUSPEND) দিয়ে জানানো হয়, কিন্তু ছাড় প্রায় ২ সেকেন্ড, আর জরুরি সাসপেন্ডে নোটিফিকেশনই আসে না।12
  • সাসপেন্ড থেকে জাগলে PBT_APMRESUMEAUTOMATIC আসে, আর ব্যবহারকারী-সূচিত জাগরণে PBT_APMRESUMESUSPENDও আসে। পুনঃসংযোগের মতো আবশ্যিক কাজ নিয়ম হিসেবে আগেরটিতে রাখুন। তবে Modern Standby-র নিম্ন-পাওয়ার আইডলে ঢোকা-বেরোনো সবসময় এই নোটিফিকেশনের সাথে মিলে না, তাই নোটিফিকেশনকে সহায়ক ধরুন।34
  • TCP সংযোগ, সিরিয়াল পোর্ট ও ডিভাইস হ্যান্ডেল জাগরণ পার করে না — এই ধারণায় ডিজাইন করুন। জাগরণ নোটিফিকেশন বা যোগাযোগ ত্রুটিতে সেগুলো নতুন করে গড়া পুনঃসংযোগ লজিকই মূল ঘটনা।
  • টাইমার ও সময় সামলানো দেখুন। পর্যায়ক্রমিক কাজ ঘুমের সময় থেমে যায়, আর জাগরণের ঠিক পরে কীভাবে ফায়ার হয় তা টাইমার API ও রানটাইম অনুযায়ী আলাদা। “অতিবাহিত সময়ে বিশাল লাফ”ও হয়, তাই নিরাপদ পথ জাগরণে সময়সূচি নতুন করে গড়া।
  • ঘুমতে না চাওয়া অংশে ঘুম স্পষ্টভাবে দমন করুন। SetThreadExecutionState (ES_SYSTEM_REQUIRED) অথবা পাওয়ার রিকোয়েস্ট (PowerSetRequest) ব্যবহার করুন, আর কাজ শেষে সবসময় খালি করুন।45
  • Modern Standby মেশিনে ঘুমের সময় সিস্টেম মাঝে মাঝে চলে, কিন্তু ডেস্কটপ অ্যাপ থেমে থাকে। “আমাদের অ্যাপ ঘুমের সময় চলতে থাকবে” ধারণা ধরে রাখা যায় না।6
  • মানক অনুসন্ধান হাতিয়ার powercfg (/requests, /lastwake, /sleepstudy) ও ইভেন্ট লগের Kernel-Power।

২. ঘুমের আশেপাশে কী হয় — পাওয়ার ইভেন্টের প্রবাহ

OS পাওয়ার-স্টেট বদল প্রতিটি অ্যাপে WM_POWERBROADCAST মেসেজ হিসেবে সম্প্রচার করে।2 ঘুম ও জাগরণ জড়িত প্রধান তিনটি ইভেন্ট আছে।

ইভেন্ট অর্থ
PBT_APMSUSPEND ঘুমে ঢুকতে যাচ্ছে (প্রস্তুতির শেষ সুযোগ)
PBT_APMRESUMEAUTOMATIC জেগেছে (জাগরণে সবসময় আসে)
PBT_APMRESUMESUSPEND ব্যবহারকারীর কাজের কারণে জাগরণ (এটি শর্তসাপেক্ষ)

PBT_APMSUSPEND ঘুমের ঠিক আগের নোটিফিকেশন, আর এখানে ফাইল বন্ধ ও স্টেট সেভ করে প্রস্তুতি নেওয়া যায়। তবে দুটি শর্ত আছে। প্রথম, প্রক্রিয়ার অনুমোদিত সময় অ্যাপপ্রতি প্রায় ২ সেকেন্ড, আর অতিক্রম করলে সিস্টেম অপেক্ষা না করে এগোয়।1 দ্বিতীয়, ব্যাটারি সংকটজনকভাবে কম থাকার মতো জরুরি সাসপেন্ডে আগাম নোটিফিকেশন ছাড়াই সঙ্গে সঙ্গে ঘুমায়2 “ঘুমের আগে শেষ করতেই হবে” ডিজাইন দাঁড়ায় না। নোটিফিকেশনকে “পারলে করুন” সুযোগ ধরুন, আর মূল কাজ জাগরণ পাশে রাখুন।

জাগরণ পাশ দুই ধাপ। সাসপেন্ড ট্রানজিশন থেকে জাগলে PBT_APMRESUMEAUTOMATIC আসে। তার উপর, পাওয়ার বোতাম বা কী প্রেসের মতো ব্যবহারকারীর কাজের কারণে জেগে থাকলে (অথবা পরে ব্যবহারকারীর উপস্থিতি ধরা পড়লে) PBT_APMRESUMESUSPEND আসে। উল্টোদিকে নেটওয়ার্কের রিমোট জাগরণ বা রক্ষণাবেক্ষণের জন্য অনাগত জাগরণে শুধু PBT_APMRESUMEAUTOMATIC আসে।3 এই দুই ধাপ নিজেই কাজ ভাগ করার ইঙ্গিত — সংযোগ নতুন করে গড়ার মতো যান্ত্রিক পুনরুদ্ধার PBT_APMRESUMEAUTOMATIC-এ করুন, আর স্ক্রিন আপডেট বা আবার-লগইন প্রম্পটের মতো ব্যবহারকারী-মুখী কাজ PBT_APMRESUMESUSPEND-এ করুন

ঘুম ও জাগরণের নোটিফিকেশন প্রবাহঘুমের ঠিক আগে PBT_APMSUSPEND আসে প্রায় ২ সেকেন্ড ছাড়সহ; জাগরণে PBT_APMRESUMEAUTOMATIC সবসময় আসে, আর PBT_APMRESUMESUSPEND শুধু ব্যবহারকারী-সূচিত জাগরণেই আসেঅ্যাপOSঅ্যাপOSঘুম (কোড চলে না)PBT_APMSUSPEND (প্রায় ২ সেকেন্ড ছাড়)স্টেট সেভ ও সংযোগ বন্ধPBT_APMRESUMEAUTOMATIC (জাগরণে আসে)পুনঃসংযোগ ও স্টেট ফেরানোPBT_APMRESUMESUSPEND (শুধু ব্যবহারকারী-সূচিত জাগরণ)স্ক্রিন আপডেট ও অন্য ব্যবহারকারী-মুখী কাজ

চিত্র ১: নোটিফিকেশন শুধু “ঠিক আগে এক কথা, আর জাগরণের পর এক বা দুই কথা”। পুনরুদ্ধারের নায়ক জাগরণ পাশের কাজ।

সাধারণ ঘুম ও জরুরি সাসপেন্ডের পার্থক্যসাধারণ ঘুমে ঠিক আগে PBT_APMSUSPEND আসে প্রায় ২ সেকেন্ড প্রস্তুতিসহ, কিন্তু সংকটজনক ব্যাটারির মতো জরুরি সাসপেন্ড আগাম নোটিফিকেশন ছাড়াই থামে, তাই আগাম নোটিফিকেশনের উপর নির্ভর করা ডিজাইন দাঁড়ায় নাসাধারণ ঘুমPBT_APMSUSPEND (প্রায় ২ সেকেন্ড ছাড়)প্রস্তুতি, তারপর থামাজরুরি সাসপেন্ড (সংকটজনক কম ব্যাটারি)আগাম নোটিফিকেশন ছাড়াই থামানোটিফিকেশন আসবে ধরে নেওয়া ডিজাইন দাঁড়ায় না

চিত্র ২: জরুরি সাসপেন্ড সতর্কতা ছাড়াই আসে। তাই প্রস্তুতি “পারলে বোনাস”, আর মূল কাজ জাগরণ পাশে যায়।

লক্ষ করুন, WM_POWERBROADCAST নিম্ন-পাওয়ার অবস্থার ধরন (ঘুম বনাম হাইবারনেশন) আলাদা করে না।4 অ্যাপের সঠিক বিমূর্ততা একে এক ধরনের ইভেন্ট হিসেবে ধরা: “থেমেছিল, আর ফিরে এসেছে”। উইন্ডোহীন সার্ভিস ও কনসোল অ্যাপ RegisterSuspendResumeNotification কলব্যাক আকারে (DEVICE_NOTIFY_CALLBACK) ব্যবহার করে একই নোটিফিকেশন পেতে পারে।7

দুই জাগরণ ধাপে কাজ ভাগ করাজাগরণে আসা PBT_APMRESUMEAUTOMATIC-এ পুনঃসংযোগের মতো যান্ত্রিক পুনরুদ্ধার রাখুন; শুধু ব্যবহারকারী-সূচিত জাগরণে আসা PBT_APMRESUMESUSPEND-এ স্ক্রিন আপডেট বা আবার-লগইন প্রম্পটের মতো ব্যবহারকারী-মুখী কাজ রাখুনPBT_APMRESUMEAUTOMATIC (জাগরণে)যান্ত্রিক পুনরুদ্ধারPBT_APMRESUMESUSPEND (ব্যবহারকারী-সূচিত জাগরণ)ব্যবহারকারী-মুখী কাজপুনঃসংযোগ ও হ্যান্ডেল আবার খোলাস্ক্রিন আপডেট ও আবার-লগইন প্রম্পট

চিত্র ৩: অনাগত জাগরণে পরেরটি আসে না, তাই আবশ্যিক পুনরুদ্ধার পরেরটিতে রাখলে মিস হবে।

৩. Modern Standby — “ঘুম”-এর অর্থ বদলে গেছে

আরেকটি আধুনিক তথ্য মাথায় নিতে হয়: Modern Standby। ঐতিহ্যবাহী S3 ঘুম ছিল “সিস্টেমকে সামগ্রিকভাবে থামানো” সরল মডেল; Modern Standby মেশিনের ঘুম স্মার্টফোন-সদৃশ মডেল যেখানে স্ক্রিন নিভে যাওয়ার পর সিস্টেম মাঝে মাঝে চলতে থাকে

ব্যবসায়িক অ্যাপের জন্য এখানে যা গুরুত্বপূর্ণ তা হলো ঘুমে ঢোকার প্রথম ধাপে Desktop Activity Moderator (DAM) ডেস্কটপ অ্যাপ থামিয়ে দেয়6 সিস্টেম নিজে নেটওয়ার্ক ধরে রাখতে ও নোটিফিকেশন পেতে মাঝে মাঝে চলে, কিন্তু সেই সুবিধা পায় যে কম্পোনেন্ট এই যন্ত্রে অংশ নেয় — সাধারণ ডেস্কটপ-অ্যাপ কোড চলে না। তাই ডেভেলপারের দৃষ্টিতে Modern Standby ও S3-এর উপসংহার একই — ঘুমের সময় আপনার কোড চলে না এই ধারণায় ডিজাইন করুন।

ঐতিহ্যবাহী ঘুম ও Modern Standby-র পার্থক্যঐতিহ্যবাহী S3 ঘুম সিস্টেমকে সামগ্রিকভাবে থামায়, আর Modern Standby-তে স্ক্রিন নিভলেও সিস্টেম মাঝে মাঝে চলে। দুই ক্ষেত্রেই DAM ডেস্কটপ অ্যাপ থামায়, তাই অ্যাপের কোড চলে নাঐতিহ্যবাহী S3 ঘুম: পুরো সিস্টেম থামেঅ্যাপের কোড চলে নাModern Standby: সিস্টেম মাঝে মাঝে চলেDAM ডেস্কটপ অ্যাপ থামায়

চিত্র ৪: মডেল বদলেছে, কিন্তু ডেস্কটপ অ্যাপের উপসংহার একই: “ঘুমের সময় চালানো যায় না”।

আরেক সতর্কতা নোটিফিকেশনের উপর কতটা নির্ভর করা যায় তার স্বল্পতা। Modern Standby-তে নিম্ন-পাওয়ার আইডলে ঢোকা-বেরোনো ঐতিহ্যবাহী সাসপেন্ড ট্রানজিশনের সাথে মেলে না, আর নোটিফিকেশন না এসেই সংযোগ ইতিমধ্যে ভাঙা থাকতে পারে। জাগরণ নোটিফিকেশনকে সহায়ক ধরুন, আর ত্রুটি শনাক্তকরণে ট্রিগার হওয়া পুনঃসংযোগ (অধ্যায় ৫) মূল পুনরুদ্ধার পথে রাখুন।

আরেক পার্থক্য আচরণের “পিচ্ছিল” অনুভূতি। ঘুমের গভীরে পৌঁছানো ধাপে ধাপে, আর বিচ্ছিন্নতা ও থামার সময় S3-এর মতো তীক্ষ্ণ নয়। “স্ক্রিন শুধু নিভেছে” আর “ঘুমিয়েছে” ব্যবহারকারীর চোখেও আলাদা করা কঠিন, তাই উপসর্গ নিলে “ঢাকনা বন্ধ করেছিল কি না” ও “কত মিনিট আইডল ছিল” নিশ্চিত করতে হয়।

৪. কী ভাঙে — ক্লাসিক উপসর্গ

TCP সংযোগ মৃত। ঘুমের সময় পক্ষ, NAT ও ফায়ারওয়াল আপনার নীরবতাকে টাইমআউট ধরে সংযোগ ফেলে দেয়। আরও খারাপ, এই পাশের সকেট ত্রুটি জানে না, তাই জাগরণের পর পাঠানো বা পাওয়ার সময়ই ব্যর্থ হয়। অথবা আরও খারাপ, রিসিভ ওয়েট কখনো ত্রুটিই দেয় না (তাই keepalive দরকার)। ডেটাবেস সংযোগ ও WebSocket-এর আকৃতি একই।

সিরিয়াল-পোর্ট ও USB-ডিভাইস হ্যান্ডেল অবৈধ হয়ে যায়। USB-সংযুক্ত ডিভাইস জাগরণে একবার “খুলে আবার লাগানো” দেখাতে পারে, আর খোলা হ্যান্ডেল ত্রুটি ফেরাতে শুরু করে। সেটাই যন্ত্র-নিয়ন্ত্রণ অ্যাপের সেই ক্লাসিক আকৃতি যা “শুধু দুপুরের পর যোগাযোগ ত্রুটি পায়”। পুনঃসংযোগ ডিজাইন সিরিয়াল-যোগাযোগ নিবন্ধেও আছে।

সময়ের ধারাবাহিকতা ভাঙে। “প্রতি ১০ সেকেন্ডে পোল” এর মতো টাইমার-চালিত কাজ ঘুমের সময় ফায়ার হয় না। জাগরণের ঠিক পরে কীভাবে ফায়ার হয় (মেয়াদোত্তীর্ণ বকেয়া কাজ সঙ্গে সঙ্গে একবার ফায়ার, পরের পর্যায় পর্যন্ত কিছু হয় না ইত্যাদি) আপনি যে টাইমার API ও রানটাইম ব্যবহার করছেন তাতে আলাদা, তাই মিস হওয়া টিক অন্তর্নিহিত আচরণে ছেড়ে দেবেন না — নিরাপদ পথ জাগরণ নোটিফিকেশনে সময়সূচি নতুন করে গড়া। আর অতিবাহিত-সময় হিসাব (আগের টাইমস্ট্যাম্প থেকে পার্থক্য) হঠাৎ “৮ ঘণ্টার মতো” হয়ে যায়, আর গড় হিসাব বা টাইমআউট বিচার ভাঙে। “প্রতি রাত ২টায় চালাও” এর মতো নির্ধারিত কাজ সেই সময়ে PC ঘুমিয়ে থাকলে চলেই না (দরকার হলে Task Scheduler-এর ঘুম-থেকে-জাগানো ফিচার দিয়ে জাগান)।

সময়ের ধারাবাহিকতা ভাঙার তিন আকৃতিপর্যায়ক্রমিক কাজ ঘুমের সময় থামে আর জাগরণ-পরবর্তী ফায়ার API অনুযায়ী আলাদা, তাই জাগরণে সময়সূচি নতুন করে গড়ুন; আগের টাইমস্ট্যাম্প থেকে পার্থক্য জাগরণের পর বিশাল হয়, তাই পাহারা দিন; নির্ধারিত কাজ ঘুমিয়ে থাকলে চলে না, তাই Task Scheduler-এর ঘুম-থেকে-জাগানো ভাবাপর্যায়ক্রমিক কাজ: থামেসময়সূচি নতুন করে গড়ুনঅতিবাহিত-সময়: ফেটে যায়অস্বাভাবিক পার্থক্য পাহারানির্ধারিত: চলেইনিঘুম-থেকে-জাগানো

চিত্র ৫: টাইমার ও সময় সামলানো “সময় লাফায়” ধারণায় লিখুন। তিন আকৃতির প্রতিটিতে এক ধরনের প্রতিরোধ আছে।

ঘুম পার করে যে তিনটি ভাঙেঘুম পার করে TCP সংযোগ পক্ষের টাইমআউটে ফেলা হয়েছে, USB ডিভাইসের হ্যান্ডেল পুনঃসংযোগ হিসেবে অবৈধ, আর অতিবাহিত-সময়ভিত্তিক কাজ বিশাল সময়-লাফ দেখে। প্রতিটিকে পুনঃসংযোগ, আবার খোলা ও পার্থক্য-পাহারা দিয়ে পুনরুদ্ধার করুনঘুমের অংশTCP: পক্ষ ফেলে দিয়েছেUSB নাকি অতিবাহিত সময়?USB: হ্যান্ডেল অবৈধঅতিবাহিত সময়: এক লাফশনাক্ত + পুনঃসংযোগডিভাইস আবার খুলুনঅস্বাভাবিক পার্থক্য পাহারা

চিত্র ৬: যা ভাঙে তা তিন পরিবারে পড়ে — “সংযোগ”, “হ্যান্ডেল” ও “সময়ের ধারাবাহিকতা” — আর প্রতিটির স্থির ধরনের পুনরুদ্ধার আছে।

শেয়ার্ড রিসোর্সে আবার অথেন্টিকেশন। নেটওয়ার্ক ড্রাইভ ও VPN প্রায়ই জাগরণের পর আবার প্রতিষ্ঠা করতে হয়, আর জাগরণের ঠিক পরে কয়েক থেকে কয়েক দশ সেকেন্ডের “স্টার্টআপ উপত্যকা” থাকে যেখানে অ্যাক্সেস ব্যর্থ হয়। জাগরণের সঙ্গে সঙ্গে সব একবারে পুনঃচেষ্টা না করে একটু অপেক্ষা করে ধাপে ধাপে পুনঃচেষ্টা করা নিরাপদ।

৫. যে অ্যাপ জাগরণ সহ্য করে সেগুলো গড়া

নীতি একটাই। “সংযোগ ও হ্যান্ডেল ঘুম পার করে না” ধরে নিন, আর অ্যাপ এমন করে সাজান যাতে সবসময় পুনরুদ্ধার করা যায়।

জাগরণ ধরে পুনরুদ্ধার করুন। টপ-লেভেল উইন্ডোর WM_POWERBROADCAST PBT_APMRESUMEAUTOMATIC পেলে ধরে রাখা সংযোগ ফেলে নতুন করে গড়ুন। বিষয়টি শুধু জাগরণ নোটিফিকেশনের উপর নির্ভর না করা। মিস হওয়া নোটিফিকেশন ও নোটিফিকেশনের আগে হওয়া যোগাযোগ দুটোই বাস্তব, তাই সবসময় “যোগাযোগ ত্রুটি ধরা পড়লে পুনঃসংযোগ” পথের সাথে জোড় করুন, আর জাগরণ নোটিফিকেশনকে শুধু সেটা আগে শুরু করার ট্রিগার ধরুন।

// C#: funnel both the resume notification and communication errors into the same reconnect path
protected override void WndProc(ref Message m)
{
    const int WM_POWERBROADCAST = 0x0218;
    const int PBT_APMRESUMEAUTOMATIC = 0x0012;
    if (m.Msg == WM_POWERBROADCAST && (int)m.WParam == PBT_APMRESUMEAUTOMATIC)
    {
        _connectionManager.RequestReconnect();   // idempotent reconnect request
    }
    base.WndProc(ref m);
}

পুনঃসংযোগ কাজ নিজে আইডেমপোটেন্ট করুন (যতবারই ডাকা হোক নিরাপদ), ব্যর্থতায় এক্সপোনেনশিয়াল ব্যাকঅফ দিয়ে পুনঃচেষ্টা করুন, আর স্থির অবস্থায় keepalive দিয়ে মৃত সংযোগ তাড়াতাড়ি ধরুন — এই তিনটি একসেট করলে শুধু ঘুম থেকে জাগরণ নয়, সংক্ষিপ্ত নেটওয়ার্ক ড্রপ বা ডিভাইস রিবুটও সহ্য হবে।

জাগরণ-সহনশীল পুনঃসংযোগ ডিজাইনজাগরণ নোটিফিকেশন, যোগাযোগ ত্রুটি ও keepalive ব্যর্থতা সব একই আইডেমপোটেন্ট পুনঃসংযোগ কাজে গিয়ে জোড়ে, যা ব্যর্থতায় এক্সপোনেনশিয়াল ব্যাকঅফ দিয়ে পুনঃচেষ্টা করেহ্যাঁনাজাগরণ নোটিফিকেশন (PBT_APMRESUMEAUTOMATIC)আইডেমপোটেন্ট পুনঃসংযোগ কাজযোগাযোগ-ত্রুটি শনাক্তকরণKeepalive ব্যর্থতাসফল?স্বাভাবিক চালনায় ফেরাএক্সপোনেনশিয়াল ব্যাকঅফের পর পুনঃচেষ্টা

চিত্র ৭: পুনঃসংযোগ এক আইডেমপোটেন্ট পথে কেন্দ্রীভূত করুন, আর জাগরণ নোটিফিকেশন, ত্রুটি শনাক্তকরণ বা keepalive থেকে একই রাস্তায় ঢুকুন।

সময় সামলানো আবার দেখুন। “গতবার থেকে অতিবাহিত সময়” ব্যবহার করা কাজে অস্বাভাবিক বড় পার্থক্য ধরলে অংশ অবৈধ করার পাহারা রাখুন (গড়ে ভাঁজ করবেন না, টাইমআউট ধরবেন না)। জাগরণ পার করে অতিবাহিত সময় মাপতে ঘুমের সময় এগোয় এমন ঘড়ি (ওয়াল-ক্লক সময়) ও কাজে সত্যি ব্যয় হওয়া সময় আলাদা রাখতে হয়।

ঘুমতে না চাওয়া অংশে ঘুম স্পষ্টভাবে দমন করুন। ঘুমানো চলবে না এমন কাজের সময় — ডেটা মাইগ্রেশন, ডিভাইসের সাথে অবিচ্ছিন্ন যোগাযোগ ইত্যাদি — SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED) দিয়ে সিস্টেম জাগিয়ে রাখা যায় (স্ক্রিনও জ্বালিয়ে রাখতে চাইলে ES_DISPLAY_REQUIRED যোগ করুন)।45 আরও ভদ্র পদ্ধতি পাওয়ার-রিকোয়েস্ট API (PowerCreateRequest + PowerSetRequest), যা কারণের স্ট্রিং লাগাতে পারে, আর powercfg /requests তখন দেখায় “কে আটকে রেখেছে ও কেন”।8 লক্ষ করুন, SetThreadExecutionState দিয়ে দমন থ্রেডপ্রতি, আর যে থ্রেড সেট করেছে সেই থ্রেড থেকেই খালি করতে হয়। async/await-এর মতো থ্রেড বদলানো কাজে হ্যান্ডেল-পরিচালিত পাওয়ার-রিকোয়েস্ট পাশ ব্যবহার করুন। সতর্কতা আছে। প্রথম, এগুলো যা দমন করে তা স্বয়ংক্রিয় আইডল ঘুম। ঢাকনা বন্ধ বা স্টার্ট মেনু থেকে Sleep বেছে নেওয়ার মতো স্পষ্ট ব্যবহারকারী-কাজ থামানো যায় না, তাই দমন চালু থাকলেও এই অধ্যায়ের পুনঃসংযোগ ডিজাইন বাদ দেওয়া যায় না। দ্বিতীয়, Modern Standby মেশিনে ব্যাটারিতে ঘুম-টাইমআউট পার হওয়ার কিছুক্ষণ পর এই পাওয়ার রিকোয়েস্টও কেটে যায়। বাধা দেওয়া যায় না এমন কাজ AC পাওয়ার বা পরিচালনা দিয়ে নিশ্চিত করতে হয়।8 তৃতীয়, কাজ শেষে সবসময় খালি করুন। খালি করতে ভুললে নতুন বাগ: “এই PC কোনো কারণে ঘুমায় না”।

ঘুম দমনের দুই উপায়সুবিধাজনক SetThreadExecutionState ব্যবহার করুন বা কারণের স্ট্রিং লাগানো ও powercfg দিয়ে প্রশাসকের চোখে দেখা যায় এমন পাওয়ার-রিকোয়েস্ট API ব্যবহার করুন, কাজ শেষে সবসময় খালি করুনঘুমানো চলবে না এমন কাজের অংশSetThreadExecutionStateপাওয়ার রিকোয়েস্ট (PowerSetRequest)সুবিধাজনক — শুধু ফ্ল্যাগকারণসহ — powercfg-এ দেখা যায়কাজ শেষে সবসময় খালি করুন

চিত্র ৮: যেকোনো উপায়েই “শেষে খালি করা” অপরিহার্য শর্ত। কারণ দেখানো যায় এমন পাওয়ার রিকোয়েস্ট পরিচালনার প্রতি দয়ালু।

সার্ভিস ও উইন্ডোহীন অ্যাপ RegisterSuspendResumeNotification (DEVICE_NOTIFY_CALLBACK) দিয়ে কলব্যাক নোটিফিকেশন পায়।7 অবিচ্ছিন্ন চালনা সত্যিকারের শর্ত হলে মূল সমাধান ঘুমায় এমন ক্লায়েন্ট PC-তে কাজ রেসিডেন্ট রাখা ডিজাইন আবার দেখা, আর সেটা সার্ভার পাশে বা ঘুম ছাড়া পরিচালিত মেশিনে সরানো।

৬. অনুসন্ধান — powercfg ও ইভেন্ট লগ

পাওয়ার ঘিরে অনুসন্ধানে OS-এর সাথে আসা হাতিয়ারই ভালো কাজ করে।

  • ঘুমায় না: powercfg /requests পাওয়ার রিকোয়েস্ট ইস্যু করা প্রক্রিয়া ও ড্রাইভার তালিকা করে। “অ্যাপ SetThreadExecutionState খালি করতে ভুলেছে” এখানেও দেখা যায়।
  • একাই জাগে: powercfg /lastwake সাম্প্রতিকতম জাগরণের কারণ দেখায়, আর powercfg /waketimers এখন মেশিন জাগাতে সংরক্ষিত টাইমার দেখায়।
  • Modern Standby গুণমান: powercfg /sleepstudy ঘুমের অংশপ্রতি পাওয়ার খরচ ও কার্যকলাপের রিপোর্ট তৈরি করে।9
  • টাইমলাইন নিশ্চিত করা: ইভেন্ট লগের (System) Kernel-Power সোর্স ঘুমে ঢোকা ও জাগরণের নথি রাখে। অ্যাপের লগের সাথে মিলিয়ে “ত্রুটির ঠিক আগে জাগরণ ছিল কি না” বস্তুনিষ্ঠভাবে নিশ্চিত করা যায়।
পাওয়ার-সমস্যার উপসর্গকে অনুসন্ধান কমান্ডে ম্যাপ করাঘুমায়-না উপসর্গে powercfg /requests দিয়ে কে পাওয়ার রিকোয়েস্ট ধরে আছে খুঁজুন; একাই-জাগে উপসর্গে /lastwake ও /waketimers দিয়ে জাগরণের কারণ খুঁজুন; টাইমলাইনের জন্য ইভেন্ট লগের Kernel-Powerঘুমায় নাpowercfg /requestsএকাই জাগেpowercfg /lastwake ও /waketimersটাইমলাইন নিশ্চিত করতে চাইইভেন্ট লগের Kernel-Powerভুলে যাওয়া ঘুম-দমনও দেখা যায়

চিত্র ৯: উপসর্গ তিন পরিবারে অনুসন্ধান কমান্ডে ম্যাপ হয়। আগে “এইমাত্র ঘুমিয়েছিল কি না” নিশ্চিত করুন, তারপর ভাগ করুন।

টিকিট সামলানোতে প্রথমেই “ঠিক আগে PC ঘুমিয়েছিল কি না (ঢাকনা বন্ধ করেছিল কি না)” জিজ্ঞাসা করলে আলাদা করা অনেক দ্রুত হয়।

৭. সারসংক্ষেপ

  • ঘুম প্রত্যাখ্যান করা যায় না। আগাম নোটিফিকেশন (PBT_APMSUSPEND) প্রায় ২ সেকেন্ড ছাড়সহ বেস্ট-এফর্ট, আর জরুরি অবস্থায় আসে না। মূল ডিজাইন জাগরণ পাশে রাখুন।
  • জাগরণ নোটিফিকেশন PBT_APMRESUMEAUTOMATIC (সাসপেন্ড থেকে জাগরণে) + PBT_APMRESUMESUSPEND (ব্যবহারকারীর কাজে)। নোটিফিকেশন না আসার জন্য ত্রুটি-চালিত পুনঃসংযোগ মূল পথে রাখুন।
  • সংযোগ ও হ্যান্ডেল জাগরণ পার করে না ধরে নিন, আর আইডেমপোটেন্ট পুনঃসংযোগ + এক্সপোনেনশিয়াল ব্যাকঅফ + keepalive-এর তিন-টুকরো সেট বাস্তবায়ন করুন।
  • অতিবাহিত-সময়ভিত্তিক কাজে “অস্বাভাবিক পার্থক্য”-এর পাহারা রাখুন। নির্ধারিত কাজ ঘুমের সময় চলে না ধরে ডিজাইন করুন।
  • ঘুমানো চলবে না এমন অংশে SetThreadExecutionState বা পাওয়ার রিকোয়েস্ট দিয়ে ঘুম স্পষ্টভাবে দমন করুন, আর শেষে সবসময় খালি করুন।
  • অনুসন্ধান powercfg (/requests, /lastwake, /sleepstudy) ও Kernel-Power ইভেন্ট লগ। টিকিট সামলানোতে প্রথমে জিজ্ঞাসা করুন “ঠিক আগে ঘুমিয়েছিল কি না”।

অ্যাপের দৃষ্টিতে ঘুম এমন ইভেন্ট যেখানে “সতর্কতা ছাড়াই সময় লাফায়, আশপাশের সংযোগ কেটে যায়, তারপর ফিরে আসে”। সেটাকে অস্বাভাবিক পরিস্থিতি না ধরে দৈনন্দিন জীবনের অংশ হিসেবে ডিজাইনে বুনেছেন কি না — সেটাই ল্যাপটপ যুগের ব্যবসায়িক অ্যাপের স্থিতিশীলতা আলাদা করে।

সম্পর্কিত নিবন্ধ

সম্পর্কিত পরামর্শ ক্ষেত্র

KomuraSoft LLC “ঘুম থেকে জাগার পর যোগাযোগ ভাঙে” ও “দুপুরের পর ডিভাইসের সংযোগ পড়ে যায়” এর মতো বাগের মূল কারণ অনুসন্ধান, বিদ্যমান অ্যাপে পুনঃসংযোগ লজিক ও পাওয়ার-ইভেন্ট হ্যান্ডলিং পরে যোগ করা, আর ল্যাপটপ চালনা ধরে নেওয়া ব্যবসায়িক অ্যাপ ও যন্ত্র-নিয়ন্ত্রণ সফটওয়্যারের ডিজাইন রিভিউ সামলায়।

তথ্যসূত্র

  1. Microsoft Learn, PBT_APMSUSPEND event। এটি সেই ইভেন্ট যা কম্পিউটার সাসপেন্ড অবস্থায় ঢোকার ঠিক আগে আসে; অ্যাপ ডেটা সেভ করতে দরকারি কাজ শেষ করবে বলে প্রত্যাশিত; এবং সিস্টেম এই নোটিফিকেশন সামলাতে প্রায় ২ সেকেন্ড দেয়, তার পর চলতে থাকলে বাধা পেতে পারে সম্পর্কে।  2

  2. Microsoft Learn, System Power Management Events। সিস্টেম ঘুমের মতো অপারেটিং-মোড বদল আগে থেকে সম্প্রচার করা; PBT_APMSUSPEND আইডল ঘুমের আগে জানানো যাতে ফাইল বন্ধ ও ডেটা সেভ করে প্রস্তুতি নেওয়া যায়; জরুরি সাসপেন্ড (সংকটজনক ব্যাটারি ইত্যাদি) আগাম নোটিফিকেশন না দেওয়া; এই মেসেজ সামলানো অ্যাপপ্রতি সর্বোচ্চ ২ সেকেন্ড অনুমোদিত ও টাইমআউটের পর কেটে যাওয়া; এবং জাগরণে প্রতিটি অ্যাপকে জানানো সম্পর্কে।  2 3

  3. Microsoft Learn, PBT_APMRESUMESUSPEND event। ব্যবহারকারী-সূচিত জাগরণে অথবা পরে ইউজার ইনপুট ধরা পড়লে PBT_APMRESUMEAUTOMATIC-এর পর এটি পাঠানো; রিমোট জাগরণের মতো বাইরের কারণে জাগরণে শুধু PBT_APMRESUMEAUTOMATIC পাঠানো; এবং অ্যাপ ঘুমের সময় বন্ধ ফাইল আবার খুলবে ও ইউজার ইনপুটের প্রস্তুতি নেবে বলে প্রত্যাশিত সম্পর্কে।  2

  4. Microsoft Learn, WM_POWERBROADCAST message। জাগরণে PBT_APMRESUMEAUTOMATIC সবসময় পাঠানো, আর ইউজার ইনপুট থেকে জাগরণে PBT_APMRESUMESUSPENDও পাঠানো; এই মেসেজ নিম্ন-পাওয়ার অবস্থার ধরন আলাদা না করা; পাওয়ার-স্টেট ট্রানজিশনের বিস্তারিত সিস্টেম ইভেন্ট লগে নথিভুক্ত; এবং সিস্টেমকে নিম্ন-পাওয়ার অবস্থায় ঢুকতে না দিতে SetThreadExecutionState ডাকা সম্পর্কে।  2 3 4

  5. Microsoft Learn, SetThreadExecutionState function (winbase.h)। ES_SYSTEM_REQUIRED ও ES_DISPLAY_REQUIRED সিস্টেমের আইডল ঘুম ও ডিসপ্লে পাওয়ার-অফ দমন করতে পারা; এবং ES_CONTINUOUS দিয়ে অবিচ্ছিন্ন দমন ঘোষণা ও শেষে শুধু ES_CONTINUOUS ডেকে খালি করা সম্পর্কে।  2

  6. Microsoft Learn, Prepare software for modern standby। Desktop Activity Moderator (DAM) Modern Standby-তে ঢোকার প্রথম ধাপে ডেস্কটপ অ্যাপ থামানো; এবং সিস্টেম তারপর ধাপে ধাপে নিম্ন-পাওয়ার পর্যায় ও রেজিলিয়েন্সি পর্যায়ে যাওয়া, শুধু অনুমোদিত কম্পোনেন্ট মাঝে মাঝে চলা সম্পর্কে।  2

  7. Microsoft Learn, RegisterSuspendResumeNotification function (winuser.h)। সাসপেন্ড/রিজিউম নোটিফিকেশন পেতে নিবন্ধনের API; এবং DEVICE_NOTIFY_CALLBACK নির্দিষ্ট করলে উইন্ডোহীন অ্যাপ বা সার্ভিস উইন্ডো হ্যান্ডেলে মেসেজ ডেলিভারির পাশাপাশি কলব্যাকে নোটিফিকেশন পেতে পারে সম্পর্কে।  2

  8. Microsoft Learn, PowerSetRequest function (winbase.h)। PowerCreateRequest দিয়ে তৈরি পাওয়ার-রিকোয়েস্ট অবজেক্টে সিস্টেম বা ডিসপ্লে জাগিয়ে-রাখার মতো রিকোয়েস্ট টাইপ সেট করা যায়; ডায়াগনস্টিক কারণের স্ট্রিং লাগানো যায়; এবং বকেয়া পাওয়ার রিকোয়েস্ট powercfg /requests দিয়ে গণনা করা যায় সম্পর্কে।  2

  9. Microsoft Learn, Modern standby SleepStudy। powercfg /sleepstudy-এর তৈরি রিপোর্ট দিয়ে Modern Standby অংশপ্রতি পাওয়ার খরচ, কার্যকলাপ ও জাগরণের কারণ (পাওয়ার বোতাম, ইউজার ইনপুট, ওয়েক টাইমার ইত্যাদি) দেখা যায় সম্পর্কে। 

কাছাকাছি বিষয়ে গভীরে যেতে একই ট্যাগযুক্ত সাম্প্রতিক নিবন্ধ।

DllMain ও লোডার লক — DLL ইনিশিয়ালাইজেশনে "কিছুই করবেন না" বলা হয় তার আসল কারণ

DllMain থেকে LoadLibrary ডাকা বা অন্য থ্রেডের সাথে সিঙ্ক্রোনাইজ করা যায় না কেন। প্রাথমিক উৎস থেকে এই নিবন্ধ ব্যাখ্যা করে লোডার লক প্রতিট...

"Not Responding" আসলে কী — Windows কীভাবে অ্যাপ হ্যাং ধরে, আর যে ডিজাইন হ্যাং করে না

Windows-এর "Not Responding" এমন যন্ত্র যেখানে OS বিচার করে উইন্ডো ৫ সেকেন্ড মেসেজ তোলেনি আর তাকে ঘোস্ট উইন্ডো দিয়ে বদলায়। এই নিবন্ধ সেই...

নেমড পাইপ ব্যবহারিকভাবে — ডিজাইন থেকে নিরাপত্তা পর্যন্ত Windows-এর মানক IPC

Windows-এর মানক আন্তঃপ্রক্রিয়া যোগাযোগ নেমড পাইপের ব্যবহারিক গাইড। প্রাথমিক উৎস থেকে এই নিবন্ধ বাইট ও মেসেজ মোডের পছন্দ, একাধিক ক্লায়েন...

Spurious Wakeup — কন্ডিশন ভেরিয়েবল কেন "নোটিফাই না হয়েও" জাগে এবং Windows-এ সঠিকভাবে কীভাবে অপেক্ষা করবেন

কন্ডিশন ভেরিয়েবলের ওয়েট নোটিফিকেশন না এলেও ফিরতে পারে (spurious wakeup)। এই নিবন্ধ Windows বাস্তবায়ন থেকে ব্যাখ্যা করে স্পেসিফিকেশন কে...

এই পৃষ্ঠাগুলো বিষয়টিকে সেবা ও সিদ্ধান্তের বৃহত্তর প্রেক্ষাপটে স্থাপন করে।

নিবন্ধটি নিচের সেবাগুলোর সাথে সরাসরি সম্পর্কিত।

প্রায়শ জিজ্ঞাসিত প্রশ্ন

এই নিবন্ধের বিষয়ে পরামর্শে প্রায়ই আসা প্রশ্ন।

অ্যাপ কি আগে থেকে ঘুম জেনে তা প্রত্যাখ্যান করতে পারে?
বর্তমান Windows-এ নোটিফিকেশন পাওয়া যায়, কিন্তু প্রত্যাখ্যান করা যায় না। ঘুমের ঠিক আগে WM_POWERBROADCAST মেসেজ PBT_APMSUSPEND ইভেন্ট পৌঁছে দেয়, আর এখানে ফাইল বন্ধ ও স্টেট সেভ করে প্রস্তুতি নেওয়া যায়, কিন্তু প্রক্রিয়ার অনুমোদিত সময় অ্যাপপ্রতি প্রায় ২ সেকেন্ড, আর অতিক্রম করলে সিস্টেম অপেক্ষা না করে এগোয়। ব্যাটারি সংকটজনকভাবে কম থাকার মতো জরুরি সাসপেন্ডে আগাম নোটিফিকেশনই আসে না। তাই "ঘুমের আগে শেষ করতেই হবে" ডিজাইন দাঁড়ায় না; কাটা যখনই আসুক জাগরণে পুনরুদ্ধার করতে পারা ডিজাইন দরকার। সত্যিই ঘুমতে না চাওয়া কাজের অংশে SetThreadExecutionState বা পাওয়ার রিকোয়েস্ট (PowerSetRequest) দিয়ে ঘুম স্পষ্টভাবে দমন করুন।
মেশিন জেগেছে তা কীভাবে ধরব?
অ্যাপে উইন্ডো থাকলে WM_POWERBROADCAST সামলান। সাসপেন্ড থেকে জাগলে PBT_APMRESUMEAUTOMATIC আসে, আর জাগরণ ব্যবহারকারীর কাজের (পাওয়ার বোতাম বা কী প্রেস) কারণে হলে তার পর PBT_APMRESUMESUSPEND আসে। সঙ্গে সঙ্গে আবার ঘুমিয়ে পড়া অনাগত জাগরণে শুধু PBT_APMRESUMEAUTOMATIC আসে, তাই পুনঃসংযোগের মতো আবশ্যিক কাজ PBT_APMRESUMEAUTOMATIC পাশে আর স্ক্রিন আপডেটের মতো ব্যবহারকারী-মুখী কাজ PBT_APMRESUMESUSPEND পাশে রাখাই মৌলিক ভাগ। উইন্ডোহীন সার্ভিস ও কনসোল অ্যাপ RegisterSuspendResumeNotification-কে DEVICE_NOTIFY_CALLBACK-এর সাথে ব্যবহার করে একই নোটিফিকেশন কলব্যাকে পেতে পারে।
ঘুমের সময় অ্যাপ চালিয়ে রাখা যায়?
নিয়ম হিসেবে না। ঘুমের সময় CPU চালনাই থেমে যায় (Modern Standby মেশিনে Desktop Activity Moderator ডেস্কটপ অ্যাপ থামিয়ে দেয়), আর অ্যাপের কোড চলে না। দুটি পছন্দ আছে। একটি শুধু কাজ চলাকালীন ঘুম দমন করা। SetThreadExecutionState-এ ES_SYSTEM_REQUIRED নির্দিষ্ট করা, অথবা PowerCreateRequest/PowerSetRequest দিয়ে পাওয়ার রিকোয়েস্ট ইস্যু করা, সেই অংশে স্বয়ংক্রিয় আইডল ঘুম দমন করে (powercfg /requests দিয়ে নিশ্চিত করা যায়)। তবু ঢাকনা বন্ধ করার মতো স্পষ্ট ঘুম-কাজ থামানো যায় না, তাই দমন চলাকালীনও জাগরণের জন্য প্রস্তুত থাকতে হয়। অন্যটি ঘুম মেনে নিয়ে "জাগরণের পর ধরে নেওয়া" ডিজাইন। রাতের ব্যাচের মতো নির্ধারিত কাজে Task Scheduler-এর "এই কাজ চালাতে কম্পিউটার জাগান" দিয়ে PC জাগানো যায়। সত্যিই অবিচ্ছিন্ন চলতে হয় এমন কাজ সার্ভারে অথবা ঘুমায় না এমন সার্ভিসে রাখুন।
জাগরণের পর TCP সংযোগ ও সিরিয়াল পোর্ট কেন কাজ করে না?
কারণ নেটওয়ার্ক অ্যাডাপ্টার ও USB ডিভাইসও ঘুমের সময় নিম্ন-পাওয়ার অবস্থায় নেমে যায়। TCP সংযোগ ইতিমধ্যে পক্ষ বা NAT/ফায়ারওয়াল টাইমআউটে ফেলে দিয়েছে, আর জাগরণের পর পাঠানো/পাওয়া ত্রুটি ফেরায় (ত্রুটি না হওয়া পর্যন্ত প্রায়ই টের পাওয়া যায় না)। USB-টু-সিরিয়াল অ্যাডাপ্টার ইত্যাদি জাগরণে ডিভাইস খুলে আবার লাগানো হিসেবে ধরা হতে পারে, আর খোলা হ্যান্ডেল অবৈধ হয়ে যায়। দুটোর জন্যই সঠিক ধারণা "হ্যান্ডেল ও সংযোগ জাগরণ পার করে না", আর সঠিক উত্তর জাগরণ নোটিফিকেশন বা যোগাযোগ ত্রুটিতে সংযোগ নতুন করে গড়া পুনঃসংযোগ লজিক। পর্যায়ক্রমিক keepalive-এর সাথে ব্যর্থতায় এক্সপোনেনশিয়াল ব্যাকঅফ পুনঃচেষ্টা জোড়াই প্রতিষ্ঠিত আকৃতি।
অপ্রত্যাশিত ঘুম বা অপ্রত্যাশিত জাগরণ কীভাবে অনুসন্ধান করব?
প্রথম হাতিয়ার powercfg কমান্ড। "ঘুমায় না" দিকে powercfg /requests তালিকা করে কোন প্রক্রিয়া ও ড্রাইভার ঘুম আটকে রাখা পাওয়ার রিকোয়েস্ট ইস্যু করেছে। "একাই জাগে" দিকে powercfg /lastwake সাম্প্রতিকতম জাগরণের কারণ দেখায় আর powercfg /waketimers এখন মেশিন জাগাতে সংরক্ষিত টাইমার দেখায়। Modern Standby মেশিনে powercfg /sleepstudy ঘুমের সময় খরচ ও কার্যকলাপের রিপোর্ট তৈরি করে। ঘুম ও জাগরণের ইতিহাস ইভেন্ট লগেও (System লগের Kernel-Power সোর্স) নথিভুক্ত, তাই "কখন ঘুমিয়েছে, আর কখন কেন জেগেছে" টাইমলাইনে নিশ্চিত করা যায়।

লেখকের প্রোফাইল

নিবন্ধের লেখকের পরিচিতি পৃষ্ঠা।

Go Komura

KomuraSoft LLC-এর প্রতিনিধি

Windows সফটওয়্যার ডেভেলপমেন্ট, প্রযুক্তিগত পরামর্শ ও বাগ তদন্তে বিশেষজ্ঞ, বিশেষ করে বিদ্যমান সিস্টেমযুক্ত প্রকল্প ও পুনরুৎপাদন করা কঠিন বাগে।

পাবলিক লিঙ্ক

ব্লগে ফিরে যান