মোবাইলে নেটওয়ার্ক রিকোয়েস্ট করা — ওয়েব থেকে পার্থক্য
এই পাঠে যা শিখবেন
- ওয়েব ও মোবাইলে নেটওয়ার্ক রিকোয়েস্টের তিনটি মূল পার্থক্য — কনটেক্সট, লাইফসাইকেল ইন্টারাপশন, ডেটা/ব্যাটারি খরচ
- ব্যাকগ্রাউন্ড গ্রেস পিরিয়ড কী এবং কেন OS এটি দেয়
- একটি সত্যিকারের ইন-ফ্লাইট রিকোয়েস্ট ট্র্যাকার — কোন রিকোয়েস্ট ব্যাকগ্রাউন্ডের আগে শেষ হয়, কোনটি গ্রেস পিরিয়ড শেষে বাতিল হয়
১ · কেন মোবাইল নেটওয়ার্কিং ওয়েব থেকে আলাদা
একটি ওয়েব পেজে একটি fetch() কল একটি স্থিতিশীল পরিবেশে চলে — পেজ ট্যাব খোলা থাকা পর্যন্ত
জাভাস্ক্রিপ্ট এক্সিকিউশন কনটেক্সট বেঁচে থাকে, রিকোয়েস্ট সাধারণত বাধাহীনভাবে শেষ হয়। মোবাইলে এই নিশ্চয়তা
নেই। ব্যবহারকারী যেকোনো মুহূর্তে হোম বাটন চাপতে পারেন, একটি কল আসতে পারে, বা OS নিজেই মেমোরি বাঁচাতে
অ্যাপটিকে ব্যাকগ্রাউন্ডে পাঠিয়ে দিতে পারে — একটি রিকোয়েস্ট মাঝপথে থাকা অবস্থাতেই।
ওয়েব পেজের মতো স্থিতিশীল "পেজ" নেই যা রিকোয়েস্টের কনটেক্সট ধরে রাখবে — অ্যাপ প্রসেসই যেকোনো সময় স্থগিত হতে পারে।
রিকোয়েস্ট চলাকালীন অ্যাপ ব্যাকগ্রাউন্ডে গেলে OS একটি ছোট্ট গ্রেস পিরিয়ড দেয়, তারপর কাজ বন্ধ করে দেয়।
প্রতিটি রিকোয়েস্ট রেডিও চালু করে, যা ব্যাটারি খরচ করে — তাই রিকোয়েস্ট ফ্রিকোয়েন্সি একটি সচেতন ডিজাইন সিদ্ধান্ত।
২ · ব্যাকগ্রাউন্ড গ্রেস পিরিয়ড
একটি অ্যাপ ব্যাকগ্রাউন্ডে গেলে iOS/Android উভয়ই সাধারণত কয়েক সেকেন্ড থেকে কয়েক মিনিট পর্যন্ত একটি
"গ্রেস পিরিয়ড" দেয় — এই সময়ের মধ্যে চলমান নেটওয়ার্ক কাজ শেষ করা যায়। এই পিরিয়ড শেষ হয়ে গেলে OS হয়
অ্যাপটিকে suspended করে দেয় (কাজ থমকে যায়) অথবা সম্পূর্ণ killed করে দেয় —
দুই ক্ষেত্রেই অসমাপ্ত রিকোয়েস্ট কার্যকরভাবে বাতিল হয়ে যায়। তাই একটি ভালো নেটওয়ার্ক ম্যানেজারকে জানতে
হয় কোন রিকোয়েস্ট "শেষ করার সুযোগ দেওয়া" আর কোনটি "সাথে সাথে বাতিল করা" উচিত।
# ইন-ফ্লাইট নেটওয়ার্ক রিকোয়েস্ট ট্র্যাকিং + ব্যাকগ্রাউন্ড-গ্রেস-পিরিয়ড পলিসি
# AppLifecycle-এর ধাঁচে বর্ধিত একটি সত্যিকারের স্টেট মেশিন ব্যবহার করে
class AppLifecycle:
ALLOWED = {
'foreground': {'background'},
'background': {'foreground', 'killed'},
'killed': set(),
}
def __init__(self):
self.state = 'foreground'
def transition(self, new_state):
if new_state in self.ALLOWED[self.state]:
self.state = new_state
return True
return False
GRACE_PERIOD_TICKS = 2 # ব্যাকগ্রাউন্ডে যাওয়ার পর এতগুলো টিক পর্যন্ত OS চলমান রিকোয়েস্ট শেষ করার সুযোগ দেয়
class NetworkManager:
def __init__(self):
self.in_flight = {} # request_id -> বাকি ticks
self.completed = {}
self.cancelled = {}
def start_request(self, request_id, ticks_to_complete):
self.in_flight[request_id] = ticks_to_complete
print(f"[শুরু] {request_id:28s} -- সম্পূর্ণ হতে {ticks_to_complete} টিক লাগবে")
def tick(self, app_state):
# প্রতিটি চলমান রিকোয়েস্টকে এক টিক এগিয়ে নেওয়া
for request_id in list(self.in_flight.keys()):
self.in_flight[request_id] -= 1
if self.in_flight[request_id] <= 0:
self.completed[request_id] = True
del self.in_flight[request_id]
print(f"[সম্পন্ন] {request_id:28s} -- app_state={app_state}")
def cancel_if_grace_expired(self, grace_remaining):
if grace_remaining <= 0:
for request_id in list(self.in_flight.keys()):
del self.in_flight[request_id]
self.cancelled[request_id] = True
print(f"[বাতিল] {request_id:28s} -- গ্রেস পিরিয়ড শেষ, OS রিকোয়েস্ট থামিয়ে দিলো")
app = AppLifecycle()
net = NetworkManager()
# রিকোয়েস্ট A: ১ টিকেই শেষ -- ব্যাকগ্রাউন্ডে যাওয়ার আগেই সম্পন্ন হবে
net.start_request("req-A(দ্রুত প্রোফাইল-লোড)", ticks_to_complete=1)
# রিকোয়েস্ট B: ৫ টিক লাগবে -- ব্যাকগ্রাউন্ডে যাওয়ার পর গ্রেস পিরিয়ডেও শেষ হবে না
net.start_request("req-B(বড় ইমেজ আপলোড)", ticks_to_complete=5)
net.tick(app.state) # টিক ১ -- ফোরগ্রাউন্ডে থাকা অবস্থায়; req-A এখানেই শেষ হবে
app.transition('background')
print(f"\n>> ইউজার হোম বাটন চাপলো -- app_state={app.state}, গ্রেস পিরিয়ড={GRACE_PERIOD_TICKS} টিক\n")
grace = GRACE_PERIOD_TICKS
net.tick(app.state) # টিক ২ -- req-B এখনো বাকি
grace -= 1
net.tick(app.state) # টিক ৩ -- req-B এখনো বাকি
grace -= 1
net.cancel_if_grace_expired(grace) # grace == 0 -- req-B বাতিল
print(f"\nসম্পন্ন হওয়া রিকোয়েস্ট: {list(net.completed.keys())}")
print(f"বাতিল হওয়া রিকোয়েস্ট: {list(net.cancelled.keys())}")
req-A মাত্র ১ টিকে শেষ হওয়ার কথা, তাই এটি অ্যাপ এখনো foreground
অবস্থাতেই সম্পন্ন হয়ে যায় — ব্যাকগ্রাউন্ডিং তাকে স্পর্শ করার আগেই। কিন্তু req-B-এর ৫ টিক লাগে;
ব্যাকগ্রাউন্ডে যাওয়ার পর মাত্র ২ টিক গ্রেস পিরিয়ড পাওয়ায় সেটি শেষ হওয়ার আগেই বাতিল হয়ে যায়। এটিই একটি
বাস্তব নীতি — "দ্রুত শেষ হওয়া রিকোয়েস্ট শেষ করার সুযোগ পায়, ধীরগতির রিকোয়েস্ট গ্রেস পিরিয়ড ফুরালে বাতিল হয়"।
মোবাইলে নেটওয়ার্ক রিকোয়েস্ট লেখার সময় শুধু "রিকোয়েস্টটি কী পাঠাবো" ভাবলেই চলে না — "অ্যাপ ব্যাকগ্রাউন্ডে গেলে এই রিকোয়েস্টের কী হবে" এই প্রশ্নেরও একটি স্পষ্ট উত্তর থাকতে হয়। পরের পাঠে (L38) আমরা দেখব একটি রিকোয়েস্ট ব্যর্থ হলে (ব্যাকগ্রাউন্ডিংয়ের কারণে বা নেটওয়ার্ক ফ্লেকিনেসের কারণে) কীভাবে বুদ্ধিমানভাবে রিট্রাই করতে হয়।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১ কেন একটি "শুধু শেষ করার সুযোগ দাও" পলিসি সব রিকোয়েস্টের জন্য নিরাপদ নয়?
কিছু রিকোয়েস্ট (যেমন একটি বড় ফাইল আপলোড) মিনিটের পর মিনিট লাগতে পারে — গ্রেস পিরিয়ড (সাধারণত কয়েক সেকেন্ড থেকে সর্বোচ্চ কয়েক মিনিট) তার জন্য যথেষ্ট নাও হতে পারে। যদি OS প্রতিটি রিকোয়েস্টকে সীমাহীন সময় ব্যাকগ্রাউন্ডে চলার অনুমতি দিতো, তাহলে ব্যাটারি ও মেমোরি দ্রুত শেষ হয়ে যেত — তাই একটি কঠোর গ্রেস পিরিয়ড প্রয়োজন।
প্র ০২
উপরের কোডে req-A-এর ticks_to_complete যদি ১-এর বদলে ৩ হতো, তাহলে কী হতো?
তাহলে প্রথম টিকে (ফোরগ্রাউন্ডে) req-A শেষ হতো না — এটি ব্যাকগ্রাউন্ডিং-এর সময়ও চলমান
থাকতো, এবং গ্রেস পিরিয়ড শেষ হওয়ার সময় req-B-এর সাথে সেটিও বাতিল হয়ে যেত। এই সিমুলেশনটি
দেখায় যে "রিকোয়েস্টের গতি" আর "লাইফসাইকেল ট্রানজিশনের সময়" এই দুটির আপেক্ষিক সম্পর্কই আসল ফলাফল ঠিক করে।
প্র ০৩
একটি ওয়েব পেজে ব্যবহারকারী ট্যাব বন্ধ করলে চলমান fetch()-এর কী হয়, এবং এটি মোবাইলের সাথে কীভাবে মেলে/আলাদা?
ট্যাব বন্ধ হলে ব্রাউজার সেই জাভাস্ক্রিপ্ট এক্সিকিউশন কনটেক্সট সম্পূর্ণ ধ্বংস করে দেয় — চলমান
fetch() কার্যকরভাবে বাতিল হয়ে যায়, অনেকটা মোবাইলের killed স্টেটের মতোই।
পার্থক্যটা হলো মোবাইলে একটি মধ্যবর্তী background স্টেট আছে (গ্রেস পিরিয়ডসহ) যা ওয়েবে
সরাসরি নেই — ওয়েব ট্যাব "ব্যাকগ্রাউন্ড ট্যাব" হিসেবে থ্রটল হয় ঠিকই, কিন্তু চলমান রিকোয়েস্ট তখনও চলতে
দেয়, বন্ধ না হওয়া পর্যন্ত।
অনুশীলন
-
চিন্তা করুন: আপনার কোনো পরিচিত অ্যাপে ভাবুন যেখানে একটি বড় আপলোড (যেমন ভিডিও শেয়ার করা)
অ্যাপ থেকে বেরিয়ে গেলেও ব্যাকগ্রাউন্ডে চলতে থাকে বলে মনে হয় — এটি কীভাবে সম্ভব বলে আপনার ধারণা?
বেশিরভাগ প্ল্যাটফর্ম একটি বিশেষ "ব্যাকগ্রাউন্ড আপলোড/ডাউনলোড টাস্ক" API দেয় যা সাধারণ গ্রেস পিরিয়ডের চেয়ে বেশি সময় পায় এবং OS নিজেই সেই ট্রান্সফারটি পরিচালনা করে, অ্যাপ প্রসেস সম্পূর্ণ সাসপেন্ড থাকলেও — এটি এই পাঠের সাধারণ ইন-ফ্লাইট রিকোয়েস্ট থেকে আলাদা একটি বিশেষায়িত মেকানিজম।
-
পরীক্ষা করুন: উপরের কোড সেলে
GRACE_PERIOD_TICKS-এর মান ২ থেকে বাড়িয়ে ৫ করুন, তারপর কোডটি আবার চালিয়ে দেখুনreq-Bএখন সম্পন্ন হয় নাকি এখনও বাতিল হয়।GRACE_PERIOD_TICKS = 5করলেreq-B-এর জন্য যথেষ্ট টিক পাওয়া যাবে (৫ টিক দরকার, ব্যাকগ্রাউন্ডে যাওয়ার পর তার জন্য যথেষ্ট গ্রেস পিরিয়ড থাকবে) — তাই এটি বাতিল না হয়ে সম্পন্ন হবে (যদি কোডে গ্রেস পিরিয়ড শেষ হওয়ার আগেই যথেষ্টtick()কল করা হয়)। এটি দেখায় গ্রেস পিরিয়ডের দৈর্ঘ্যই নির্ধারণ করে কোন রিকোয়েস্ট বাঁচবে।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৫৭টি পাঠ অ্যাপ লাইফসাইকেল, মোবাইল UI/UX, MVVM/MVI আর্কিটেকচার, নেটিভ বনাম ক্রস-প্ল্যাটফর্ম, নেভিগেশন, স্টেট ম্যানেজমেন্ট, লোকাল স্টোরেজ, ডিভাইস ফিচার ও ডিপ্লয়মেন্ট — বাকি পাঠগুলো শীঘ্রই যুক্ত হবে।
- FSWF · REST আর্কিটেকচারাল প্রিন্সিপল সহোদর পাঠ REST রিকোয়েস্ট করার সাধারণ নিয়ম ও নীতিগুলো এই পাঠেই বিস্তারিত শেখানো হয়েছে।
- সব Courses দেখুন ABCL TECH C, C++, Python, Java, JavaScript, DSA, DBMS, Discrete Mathematics, System Design, Cybersecurity, Cloud Computing & DevOps, Computer Networks, Operating Systems, Computer Architecture, Programming Languages & Compiler Design, Software Engineering & Git, Theory of Computation, Engineering Economics, Full-Stack Web Frameworks ও Mobile App Development — সব এক জায়গায়।