Kotlin এবং GraalVM এর সাথে AWS Lambda সমস্যা সমাধান: কেন মৃত্যুদন্ড বন্ধ হবে না
Kotlin এবং GraalVM-এ AWS Lambda ফাংশন চালানো বড় কর্মক্ষমতা সুবিধা প্রদান করতে পারে, কিন্তু অপ্রত্যাশিত অসুবিধা যেমন অনির্দিষ্টকালের জন্য কার্যকর করা হতে পারে। Kotlin-ভিত্তিক Lambda এবং GraalVM নেটিভ ইমেজগুলির সাথে কাজ করার সময়, একটি সাধারণ সমস্যা হল যে প্রতিক্রিয়া পাওয়া সত্ত্বেও ফাংশনটি চিরতরে চলে।
এই সমস্যাটি সাধারণত ঘটে যখন বুটস্ট্র্যাপ স্ক্রিপ্ট রানটাইম পরিবেশ সঠিকভাবে পরিচালনা করতে ব্যর্থ হয়, যার ফলে প্রতিক্রিয়া পাঠানোর পরেও ফাংশন সক্রিয় থাকে। বুটস্ট্র্যাপ ফাইলে ভুল কনফিগারেশন বা ফাংশন কোডের মধ্যে অনুপযুক্ত প্রতিক্রিয়া প্রক্রিয়াকরণ প্রায়শই সমস্যার উৎস।
এই সমস্যাটির সাথে কাজ করে এমন ডেভেলপারদের বুঝতে হবে কিভাবে AWS Lambda আমন্ত্রণ লাইফসাইকেল বজায় রাখে এবং যখন কার্যকর করার পরিবেশ সঠিক সমাপ্তির সংকেত না পায় তখন কী ঘটে। এতে 'অবৈধ অনুরোধ আইডি' বা রানটাইম সেটআপের সমস্যা সমাধানের মতো ত্রুটির বার্তা মূল্যায়ন করা যেতে পারে।
এই পোস্টে, আমরা অসীম মৃত্যুদন্ডের সমস্যার মৌলিক কারণগুলি দেখব এবং এটি ঠিক করার জন্য ব্যবহারিক সমাধান উপস্থাপন করব। বুটস্ট্র্যাপ ফাইল, কোটলিন ফাংশন লজিক এবং AWS Lambda সেটিংসের উপর ফোকাস করে, আপনি এই সমস্যার সমাধান করতে পারেন এবং নিশ্চিত করতে পারেন যে Lambda মসৃণভাবে চলছে।
আদেশ | ব্যবহারের উদাহরণ |
---|---|
set -euo pipefail | এই কমান্ডটি শেল স্ক্রিপ্টে ব্যবহার করা হয় কঠোর ত্রুটি পরিচালনার জন্য। এটি নিশ্চিত করে যে কোনো কমান্ড (-e) ব্যর্থ হলে স্ক্রিপ্ট অবিলম্বে বন্ধ হয়ে যায়, অনির্ধারিত ভেরিয়েবল (-u) প্রতিরোধ করে এবং পাইপলাইনে ত্রুটি সনাক্তকরণে সহায়তা করে (-o পাইপফেল)। |
handle_error() | এডব্লিউএস ল্যাম্বডায় বিশদ ত্রুটির তথ্য লগিং এবং পাঠানোর জন্য একটি কাস্টম ফাংশন, বুটস্ট্র্যাপ প্রক্রিয়া চলাকালীন কার্যকরী সমস্যাগুলি ক্যাপচার করা এবং সঠিকভাবে পরিচালনা করা হয়েছে তা নিশ্চিত করে। |
curl -sI | এই কমান্ড AWS Lambda রানটাইম API থেকে শুধুমাত্র HTTP প্রতিক্রিয়া শিরোনাম পুনরুদ্ধার করে। এটি পরবর্তী প্রক্রিয়াকরণের জন্য প্রয়োজনীয় মেটাডেটা সংগ্রহ করতে ব্যবহৃত হয়, যেমন অনুরোধ আইডি। |
tr -d '\r\n' | শিরোনাম থেকে অনুরোধ আইডি প্রক্রিয়া করার সময় স্ট্রিং থেকে নতুন লাইনের অক্ষরগুলি সরাতে এটি ব্যবহার করা হয়। স্ক্রিপ্টে আরও ব্যবহারের জন্য স্ট্রিং মানগুলি সঠিকভাবে ফর্ম্যাট করা হয়েছে তা নিশ্চিত করা গুরুত্বপূর্ণ। |
Gson().fromJson() | Kotlin ফাংশন কোটলিন অবজেক্টে JSON ইভেন্ট ডেটা ডিসিরিয়ালাইজ করতে Gson ব্যবহার করে, Lambda ফাংশনকে জটিল ইভেন্ট পেলোডগুলি পরিচালনা করার অনুমতি দেয়। ল্যাম্বডাতে JSON ইনপুট প্রক্রিয়াকরণের জন্য এটি গুরুত্বপূর্ণ। |
finally | কোটলিন ফাংশনের 'অবশেষে' ব্লকটি নিশ্চিত করে যে কিছু কার্যক্রম (যেমন লগিং) সম্পন্ন হয়েছে তা নির্বিশেষে নির্বিশেষে কার্যকর করার সময় একটি ত্রুটি ঘটবে, যার ফলশ্রুতিতে সমাপ্তি ঘটবে। |
assertEquals() | এই কমান্ডটি কোটলিন টেস্ট লাইব্রেরির অংশ এবং ল্যাম্বডা ফাংশন লজিক সঠিক কিনা তা নিশ্চিত করে প্রত্যাশিত এবং প্রকৃত আউটপুটগুলির তুলনা করতে ইউনিট পরীক্ষায় ব্যবহৃত হয়। |
cut -d' ' -f2 | একটি বিভাজনের উপর ভিত্তি করে স্ট্রিং বিভক্ত করার জন্য একটি কমান্ড (এই ক্ষেত্রে, একটি স্থান) এবং একটি নির্দিষ্ট ক্ষেত্র নির্বাচন করা। এটি AWS Lambda দ্বারা ফেরত HTTP শিরোনাম থেকে অনুরোধ আইডি নিষ্কাশনের সুবিধা দেয়৷ |
continue | যদি একটি শর্ত পূরণ করা হয়, যেমন যখন অনুরোধ আইডি সনাক্ত করা যাবে না, স্ক্রিপ্টটি লুপে বর্তমান পুনরাবৃত্তির বাকি অংশটি এড়িয়ে যাবে, এটি পরবর্তী আহ্বানের জন্য অপেক্ষা করার অনুমতি দেবে। |
কোটলিন ল্যাম্বডা এবং বুটস্ট্র্যাপ স্ক্রিপ্টগুলি কীভাবে কাজ করে
নমুনার প্রথম স্ক্রিপ্টটি একটি GraalVM নেটিভ ইমেজ পরিবেশে AWS Lambda ফাংশন চালানোর জন্য একটি বুটস্ট্র্যাপ শেল স্ক্রিপ্ট। এই স্ক্রিপ্টটি অসংখ্য ফাংশন সম্পাদন করে, যার মধ্যে AWS থেকে আগত অনুরোধের জন্য অপেক্ষা করা, সেগুলিকে প্রক্রিয়া করা এবং প্রতিক্রিয়া ফেরত দেওয়া। লুপ, যা ক্রমাগত নতুন আহ্বানের জন্য অপেক্ষা করে, স্ক্রিপ্টের প্রধান উপাদান। AWS Lambda এর রানটাইম API এর সাথে ইন্টারফেস করতে কার্ল ব্যবহার করে, এটি পৃথকভাবে হেডার এবং ইভেন্ট ডেটা উভয়ই পায়। শিরোনাম থেকে অনুরোধ আইডি পার্স করা প্রক্রিয়াটির একটি গুরুত্বপূর্ণ পদক্ষেপ কারণ এটি প্রতিটি উত্তরকে সংশ্লিষ্ট অনুরোধের সাথে সংযুক্ত করতে সহায়তা করে।
লগিংও স্ক্রিপ্টের একটি গুরুত্বপূর্ণ অংশ। দ লগ_বার্তা ফাংশন ল্যাম্বডা নির্বাহের বিভিন্ন পর্যায়ে প্রাসঙ্গিক তথ্য প্রদান করে, যেমন একটি আহ্বানের জন্য অপেক্ষা করা বা কোটলিন ফাংশন চালানো। দ হ্যান্ডেল_ত্রুটি ফাংশন গুরুত্বপূর্ণ ত্রুটি পরিচালনার ক্ষমতা প্রদান করে। এটি সমস্যাগুলি লগ করে এবং অ্যামাজন ওয়েব পরিষেবাগুলিতে বিশদ ব্যর্থতার উত্তর পাঠায়, যার মধ্যে ত্রুটি বার্তা, প্রস্থান স্থিতি এবং স্ট্যাক ট্রেস অন্তর্ভুক্ত রয়েছে। এইভাবে, মৃত্যুদন্ডের সময় যেকোন ত্রুটি স্বীকৃত এবং যথাযথভাবে চিকিত্সা করা হয়, নীরব ব্যর্থতা প্রতিরোধ করে।
Kotlin ফাংশন, যা বুটস্ট্র্যাপ স্ক্রিপ্ট দ্বারা নির্বাহ করা হয়, AWS Lambda দ্বারা প্রেরিত ইভেন্ট ডেটা প্রক্রিয়া করে। এটি প্রাথমিকভাবে Gson ব্যবহার করে একটি JSON অবজেক্টে ইভেন্ট ডেটা পার্স করার আগে ইনপুটটি বিদ্যমান কিনা তা নির্ধারণ করে। ফাংশনটি ইভেন্টটি প্রক্রিয়া করে এবং একটি প্রতিক্রিয়া তৈরি করে, যা তারপর JSON বিন্যাসে সিরিয়াল করা হয়। এই JSON আউটপুটটি কনসোলে লেখা হয়, যা পরে বুটস্ট্র্যাপ স্ক্রিপ্ট দ্বারা ক্যাপচার করা হয় এবং চূড়ান্ত প্রতিক্রিয়া হিসাবে AWS Lambda-এ ফিরে আসে। উল্লেখযোগ্যভাবে, ফাংশনটি কার্যকর করার সময় যেকোন রানটাইম ব্যতিক্রমগুলি পরিচালনা করতে ট্রাই-ক্যাচ ব্লকগুলিকে অন্তর্ভুক্ত করে, মসৃণ ত্রুটি পরিচালনা নিশ্চিত করে।
ল্যাম্বডার কার্যকারিতা মূল্যায়ন করার জন্য, ইউনিট পরীক্ষাগুলি কোটলিনের পরীক্ষার কাঠামো ব্যবহার করে লেখা হয়েছিল। এই পরীক্ষাগুলি বিভিন্ন পরিস্থিতির প্রতিলিপি করে, যেমন ইনপুট সহ এবং ছাড়াই পদ্ধতিতে কল করা। assertEquals এর মত দাবী ব্যবহার করে, আমরা নিশ্চিত করতে পারি যে পদ্ধতিটি সঠিকভাবে আচরণ করছে। তদ্ব্যতীত, কোটলিন ফাংশনের মধ্যে একটি অবশেষে ব্লক ব্যবহার করা নিশ্চিত করে যে ল্যাম্বডা পরিষ্কারভাবে প্রস্থান করে, এমনকি ব্যতিক্রমের ক্ষেত্রেও। এই পরীক্ষার কেসগুলি নিশ্চিত করে যে ল্যাম্বডা ফাংশন বিভিন্ন সেটিংস এবং ইনপুট পরিস্থিতিতে কাজ করে, কোডটিকে আরও স্থিতিস্থাপক এবং বিশ্বস্ত করে তোলে।
সমাধান 1: শেলে AWS Lambda বুটস্ট্র্যাপ স্ক্রিপ্ট এক্সিকিউশন উন্নত করা
এই পদ্ধতিটি Bash-এ AWS Lambda বুটস্ট্র্যাপ স্ক্রিপ্টের উন্নতির উপর ফোকাস করে যাতে প্রতিক্রিয়া পাঠানোর পরে এক্সিকিউশন সম্পূর্ণ হয়।
#!/bin/sh
set -euo pipefail
echo "Bootstrap script started" >&2
# Function to log messages
log_message() {
echo "$(date): $1" >&2
}
# Function to handle errors
handle_error() {
local exit_status=$1
local error_message=$2
local request_id=$3
log_message "Error: $error_message (Exit: $exit_status)"
ERROR_URL="http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$request_id/error"
ERROR="{\"errorMessage\": \"$error_message\", \"errorType\": \"RuntimeError\", \"stackTrace\": [\"Exit: $exit_status\"]}"
curl -s -X POST "$ERROR_URL" -d "$ERROR" --header "Lambda-Runtime-Function-Error-Type: RuntimeError"
}
RUNTIME_API="http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime"
while true; do
log_message "Waiting for next invocation"
HEADERS=$(curl -sI "${RUNTIME_API}/invocation/next")
EVENT_DATA=$(curl -s "${RUNTIME_API}/invocation/next")
REQUEST_ID=$(echo "$HEADERS" | grep -i Lambda-Runtime-Aws-Request-Id | cut -d' ' -f2 | tr -d'\r\n')
if [ -z "$REQUEST_ID" ]; then
log_message "No Request ID found, continuing..."
continue
fi
log_message "Executing Kotlin Lambda"
RESPONSE=$(./AWS-Lambda-Kotlin "$EVENT_DATA" 2>&1)
EXIT_STATUS=$?
if [ "$EXIT_STATUS" -ne 0 ]; then
handle_error $EXIT_STATUS "Kotlin execution failed" "$REQUEST_ID"
continue
fi
RESPONSE_URL="${RUNTIME_API}/invocation/$REQUEST_ID/response"
curl -s -X POST "$RESPONSE_URL" -d "$RESPONSE"
log_message "Execution complete"
exit 0
done
সমাধান 2: সঠিক প্রস্থান এবং ত্রুটি হ্যান্ডলিং সহ কোটলিন ফাংশন
এই সমাধানটি ইনপুটগুলি পরিচালনা করার জন্য Kotlin Lambda ফাংশনের ক্ষমতাকে উন্নত করে এবং উত্তর দেওয়ার পরে ফাংশনটি বন্ধ হয়ে যায় তা নিশ্চিত করে।
fun main(args: Array<String>) {
try {
println("Kotlin Lambda started")
if (args.isEmpty()) {
println("No input received")
return
}
val eventData = args[0]
println("Event data: $eventData")
val gson = Gson()
val jsonEvent = gson.fromJson(eventData, JsonObject::class.java)
val result = JsonObject()
result.addProperty("message", "Processed successfully")
result.add("input", jsonEvent)
val jsonResponse = gson.toJson(result)
println(jsonResponse)
} catch (e: Exception) {
val errorResponse = JsonObject()
errorResponse.addProperty("errorMessage", e.message)
errorResponse.addProperty("errorType", e.javaClass.simpleName)
println(Gson().toJson(errorResponse))
} finally {
println("Lambda execution complete, terminating.")
}
}
সমাধান 3: AWS Lambda Kotlin ফাংশনের জন্য ইউনিট পরীক্ষা
এই সমাধানটি বিভিন্ন ইনপুট এবং পরিস্থিতিতে ফাংশনটি প্রত্যাশিত হিসাবে কাজ করে তা যাচাই করার জন্য কোটলিন ইউনিট পরীক্ষা প্রদান করে।
import org.junit.Test
import kotlin.test.assertEquals
class LambdaTest {
@Test
fun testLambdaWithValidInput() {
val args = arrayOf("{\"key1\":\"value1\"}")
val output = executeLambda(args)
assertEquals("Processed successfully", output)
}
@Test
fun testLambdaWithNoInput() {
val args = arrayOf()
val output = executeLambda(args)
assertEquals("No input received", output)
}
private fun executeLambda(args: Array<String>): String {
// Simulates running the Lambda function
return LambdaFunction().main(args)
}
}
ল্যাম্বডা টাইমআউট এবং এক্সিকিউশন লাইফসাইকেল সমস্যাগুলি সমাধান করা
GraalVM এবং Kotlin-এর সাথে AWS Lambda-এর সাথে কাজ করার সময় Lambda এক্সিকিউশন লাইফসাইকেল বোঝা অত্যন্ত গুরুত্বপূর্ণ। একটি GraalVM নেটিভ ইমেজ স্থাপন করার সময়, ল্যাম্বডাকে অবশ্যই দক্ষতার সাথে অনুরোধগুলি পরিচালনা করতে হবে এবং প্রতিক্রিয়া পাঠানোর পরে কার্যকর করা বন্ধ করতে হবে। একটি সাধারণ সমস্যা হল যে Lambda সঠিকভাবে প্রতিক্রিয়া প্রদান করার পরে চিরতরে চলে। এই সমস্যাটি প্রায়শই বুটস্ট্র্যাপ স্ক্রিপ্টে এবং কীভাবে AWS রানটাইম API কার্যকর করার সময় পরিচালিত হয় তা ট্র্যাক করা হয়। বিশেষভাবে, স্ক্রিপ্টকে অবশ্যই গ্যারান্টি দিতে হবে যে এটি পরবর্তী আহ্বানের জন্য সঠিকভাবে অপেক্ষা করবে বা শেষ প্রতিক্রিয়া প্রদান করার পরে প্রস্থান করবে।
অনেক পরিস্থিতিতে, এই সমস্যাটি ঘটে যখন রিকোয়েস্ট আইডি সঠিকভাবে পার্স বা পরিচালনা করা হয় না, যার ফলে AWS-এ ভুল প্রতিক্রিয়া ম্যাপিং হয়। যদি Lambda অনুরোধ এবং প্রতিক্রিয়া লাইফসাইকেলের সাথে মেলে না, AWS একটি ত্রুটি ফেরত দিতে পারে যেমন InvalidRequestID বা শুধুমাত্র সর্বোচ্চ অনুমোদিত কার্যকর করার সময় পরে ঘড়ি আউট। ফলস্বরূপ, বুটস্ট্র্যাপ স্ক্রিপ্ট এবং কোটলিন পদ্ধতি উভয় ক্ষেত্রেই ত্রুটি হ্যান্ডলিং শক্তিশালী হতে হবে। এর মধ্যে রয়েছে স্পষ্ট লগ পাঠানো, ব্যর্থ অনুরোধগুলি পরিচালনা করা এবং নিশ্চিত করা যে সমস্ত API এন্ডপয়েন্ট সঠিকভাবে অ্যাক্সেসযোগ্য এবং কার্যকর করার সময় পরিচালিত।
বিবেচনা করার জন্য আরেকটি গুরুত্বপূর্ণ উপাদান হল GraalVM অপ্টিমাইজেশনের বাস্তবায়ন। যদিও GraalVM কোটলিন-ভিত্তিক ল্যাম্বডাসের জন্য উচ্চ-পারফরম্যান্স এক্সিকিউশন প্রদান করে, সেখানে বেশ কিছু বিশদ বিবরণ রয়েছে, বিশেষ করে কিভাবে নেটিভ ইমেজ AWS Lambda আর্কিটেকচারের সাথে ইন্টারঅ্যাক্ট করে। মেমরির ব্যবহার কমাতে কোটলিন ফাংশন অপ্টিমাইজ করা, সঠিক ত্রুটি প্রচার, এবং সুন্দর শাটডাউন অসীম এক্সিকিউশন লুপের সম্মুখীন হওয়ার সম্ভাবনা উল্লেখযোগ্যভাবে হ্রাস করতে পারে। এই সমস্ত সর্বোত্তম অনুশীলনগুলিকে একত্রিত করার ফলে মসৃণ স্থাপনা এবং আরও নির্ভরযোগ্য ল্যাম্বডা কর্মক্ষমতা দেখা যায়।
GraalVM এবং Kotlin এর সাথে AWS Lambda সম্পর্কিত প্রায়শ জিজ্ঞাস্য প্রশ্নাবলী
- আমি কিভাবে কোটলিন ব্যবহার করে AWS Lambda এ অবিরাম মৃত্যুদন্ড এড়াতে পারি?
- নিশ্চিত করুন যে আপনার বুটস্ট্র্যাপ স্ক্রিপ্ট সঠিকভাবে অনুরোধের জীবনচক্র পরিচালনা করে এবং প্রতিক্রিয়া পাঠানোর পরে প্রস্থান করে। সমস্যাগুলি ক্যাপচার করতে কার্যকর ত্রুটি হ্যান্ডলিং ব্যবহার করুন।
- "অবৈধ অনুরোধ আইডি" ত্রুটির কারণ কী?
- এই সমস্যাটি সাধারণত ঘটে যখন AWS রানটাইম হেডার থেকে রিকোয়েস্ট আইডি সঠিকভাবে পার্স করা হয় না, যার ফলে রেসপন্স ম্যাপিংয়ে অসঙ্গতি দেখা দেয়।
- আমি GraalVM ব্যবহার করে Lambda ফাংশন অপ্টিমাইজ করতে পারি?
- হ্যাঁ, GraalVM কর্মক্ষমতা উন্নত করে; যাইহোক, ন্যূনতম মেমরি ব্যবহার এবং সঠিক ত্রুটি পরিচালনার জন্য আপনার কোটলিন ফাংশন টিউন করা গুরুত্বপূর্ণ।
- আমি কিভাবে ল্যাম্বডা টাইমআউট সমস্যাগুলি ডিবাগ করব?
- বুটস্ট্র্যাপ স্ক্রিপ্ট-এ অস্বাভাবিক ব্যর্থতা বা অসীম লুপের জন্য ল্যাম্বডা লগ চেক করুন। পুঙ্খানুপুঙ্খ প্রতিক্রিয়া রাখা উৎসকে বিচ্ছিন্ন করতে সাহায্য করতে পারে।
- কেন আমার ল্যাম্বডা ফাংশন অনির্দিষ্টকালের জন্য চলছে?
- এটি প্রায়শই ভুল ত্রুটি হ্যান্ডলিং বা বুটস্ট্র্যাপ স্ক্রিপ্ট-এ প্রধান এক্সিকিউশন লুপ এড়িয়ে যেতে ব্যর্থতার কারণে ঘটে। নিশ্চিত করুন যে ইভেন্টটি পরিচালনা করার পরে Lambda ফাংশন চলে গেছে।
GraalVM-এর সাথে AWS Lambda-এর চূড়ান্ত চিন্তা-ভাবনা
GraalVM-এর সাথে Kotlin-ভিত্তিক AWS Lambda ফাংশন চালানোর সময়, জীবনচক্র সঠিকভাবে পরিচালনা করা গুরুত্বপূর্ণ। বুটস্ট্র্যাপ ফাইলে ভুল কনফিগারেশন বা ভ্রান্ত অনুরোধ-প্রতিক্রিয়া ম্যাপিং প্রায়শই অনির্দিষ্টকালের জন্য কার্যকর হয়, যা মসৃণ ফাংশন সমাপ্তিতে বাধা দেয়। অনুরোধ আইডি সঠিকভাবে ব্যাখ্যা করা এবং প্রাসঙ্গিক সংকেত পাঠানো নিশ্চিত করে যে ফাংশনটি সফলভাবে সম্পন্ন হয়েছে।
বুটস্ট্র্যাপ স্ক্রিপ্ট এবং কোটলিন ফাংশনে ত্রুটি পরিচালনার অপ্টিমাইজ করা সম্ভাব্য সমস্যাগুলির প্রাথমিক সনাক্তকরণের অনুমতি দেয়। তদ্ব্যতীত, কার্যকর করার পরে ফাংশনটি সুন্দরভাবে চলে যায় তা নিশ্চিত করা AWS Lambda টাইমআউট প্রতিরোধে সহায়তা করতে পারে। এই সর্বোত্তম অনুশীলনের ফলে একটি আরও স্থিতিশীল এবং দক্ষ সার্ভারহীন সিস্টেম।
সূত্র এবং তথ্যসূত্র
- AWS Lambda এক্সিকিউশন লাইফসাইকেল এবং GraalVM নেটিভ ইমেজ সম্পর্কিত তথ্য AWS ডকুমেন্টেশন থেকে উল্লেখ করা হয়েছে। আরো বিস্তারিত জানার জন্য, দেখুন এডব্লিউএস ল্যাম্বদা .
- GraalVM এর সাথে Kotlin-ভিত্তিক AWS Lambda ফাংশনগুলি পরিচালনা করার কৌশলগুলি GraalVM অফিসিয়াল ডকুমেন্টেশন থেকে আঁকা হয়েছে। এ আরো দেখুন GraalVM .
- বুটস্ট্র্যাপ স্ক্রিপ্ট ত্রুটি পরিচালনার জন্য সর্বোত্তম অনুশীলনগুলি ল্যাম্বডা এক্সিকিউশন ইস্যুতে সম্প্রদায়ের নিবন্ধগুলি থেকে প্রাপ্ত হয়েছিল, যেমন স্ট্যাক ওভারফ্লো .