यह प्रश्न मुझे कुछ समय के लिए परेशान करता है (मुझे आशा है कि मैं केवल एक ही नहीं हूं)। मैं एक सामान्य 3-स्तरीय जावा ईई ऐप लेना चाहता हूं और देख सकता हूं कि यह संभवतः अभिनेताओं के साथ कैसे लागू किया जा सकता है। मैं यह जानना चाहता हूं कि क्या यह वास्तव में इस तरह के संक्रमण को करने के लिए कोई समझ में आता है और अगर इससे समझ में आता है तो मैं इसका लाभ कैसे प्राप्त कर सकता हूं (शायद प्रदर्शन, बेहतर वास्तुकला, विस्तारशीलता, रखरखाव, आदि ...)।अभिनेताओं को सामान्य 3-स्तरीय आर्किटेक्चर स्थानांतरित करना
trait UserDao {
def getUsers(): List[User]
def getUser(id: Int): User
def addUser(user: User)
}
trait UserService {
def getUsers(): List[User]
def getUser(id: Int): User
def addUser(user: User): Unit
@Transactional
def makeSomethingWithUsers(): Unit
}
@Controller
class UserController {
@Get
def getUsers(): NodeSeq = ...
@Get
def getUser(id: Int): NodeSeq = ...
@Post
def addUser(user: User): Unit = { ... }
}
आप कई वसंत अनुप्रयोगों में कुछ इस तरह पा सकते हैं:
यहाँ ठेठ नियंत्रक (प्रस्तुति), सेवा (व्यवसाय तर्क), डीएओ (डेटा) कर रहे हैं। हम सरल कार्यान्वयन कर सकते हैं जिसमें कोई साझा स्थिति नहीं है और ऐसा इसलिए है क्योंकि इसमें सिंक्रनाइज़ किए गए ब्लॉक नहीं हैं ... इसलिए सभी राज्य डेटाबेस में हैं और एप्लिकेशन लेनदेन पर निर्भर करता है। सेवा, नियंत्रक और दाओ के पास केवल एक उदाहरण है। तो प्रत्येक अनुरोध के लिए आवेदन सर्वर अलग थ्रेड का उपयोग करेगा, लेकिन धागे एक दूसरे को अवरुद्ध नहीं करेंगे (लेकिन डीबी आईओ द्वारा अवरुद्ध किया जाएगा)।
मान लीजिए कि हम अभिनेताओं के साथ समान कार्यक्षमता को लागू करने की कोशिश कर रहे हैं। यह इस तरह दिख सकता है:
sealed trait UserActions
case class GetUsers extends UserActions
case class GetUser(id: Int) extends UserActions
case class AddUser(user: User) extends UserActions
case class MakeSomethingWithUsers extends UserActions
val dao = actor {
case GetUsers() => ...
case GetUser(userId) => ...
case AddUser(user) => ...
}
val service = actor {
case GetUsers() => ...
case GetUser(userId) => ...
case AddUser(user) => ...
case MakeSomethingWithUsers() => ...
}
val controller = actor {
case Get("/users") => ...
case Get("/user", userId) => ...
case Post("/add-user", user) => ...
}
मुझे लगता है कि यह बहुत महत्वपूर्ण नहीं है कि कैसे() और पोस्ट() निकालने वाले यंत्र लागू किए जाते हैं। मान लीजिए कि मैं इसे लागू करने के लिए एक ढांचा लिखता हूं। मैं इस तरह नियंत्रक को संदेश भेज सकता हूं:
controller !! Get("/users")
वही बात नियंत्रक और सेवा द्वारा की जाएगी। इस मामले में पूरा वर्कफ़्लो तुल्यकालिक होगा। इससे भी बदतर - मैं समय पर केवल एक ही अनुरोध को संसाधित कर सकता हूं (इस बीच सभी अन्य अनुरोध नियंत्रक के मेलबॉक्स में उतरेंगे)। तो मुझे इसे सभी असीमित बनाने की जरूरत है।
क्या इस सेटअप में प्रत्येक प्रोसेसिंग चरण को असीमित रूप से करने का कोई शानदार तरीका है?
जहां तक मैं समझता हूं कि प्रत्येक स्तर को किसी संदेश को उस संदेश के संदर्भ को सहेजना चाहिए जो उसे प्राप्त होता है और फिर नीचे दिए गए स्तर पर संदेश भेजता है। जब कुछ परिणाम संदेश के साथ जवाब के नीचे स्तर होता है तो मुझे प्रारंभिक संदर्भ को पुनर्स्थापित करने और मूल प्रेषक को इस परिणाम के साथ उत्तर देने में सक्षम होना चाहिए। क्या ये सही है?
इसके अलावा, इस समय मेरे पास प्रत्येक स्तर के लिए अभिनेता का केवल एक उदाहरण है। भले ही वे असीमित रूप से काम करेंगे, फिर भी मैं समानांतर केवल एक नियंत्रक, सेवा और दाओ संदेश में संसाधित कर सकता हूं। इसका मतलब है कि मुझे एक ही प्रकार के अधिक अभिनेताओं की आवश्यकता है। जो मुझे प्रत्येक स्तर के लिए लोडबैलेंसर की ओर ले जाता है। इसका मतलब यह भी है कि अगर मेरे पास UserService और ItemService है तो मुझे लोडबेलस दोनों अलग-अलग होना चाहिए।
मुझे लगता है कि मैं कुछ गलत समझता हूं। सभी आवश्यक विन्यास को अधूरा लगता है। आप इस बारे में क्या सोचते हैं?
(पुनश्च: यह भी बहुत पता है कि कैसे डीबी लेनदेन इस तस्वीर में फिट दिलचस्प होगा, लेकिन मुझे लगता है कि इस सूत्र के लिए overkill है)
+1 - आपके द्वारा महत्वाकांक्षी सामान, आसान एंजेल। – duffymo