چیزی که از شما در این سوال میخواهیم، یک حافظهی نهان (Cache) از نوع کلید و مقداری است. این حافظهی نهان، اطلاعات را داخل دیسک نگهداری نمیکند و از نوع «داخل حافظهای» است.
تا اینجا احتمالاً ذهنتان سمت Redis رفته است، اما این حافظه به شکل خاص برای زبان Go طراحی شده و از امکانات این زبان بهره میبرد. به طور خاص برای اتصال از سمت کاربر به حافظهی نهان از چنلها استفاده میشود.
روال کار استفاده از حافظهی نهان را میتوان به این شکل خلاصه کرد:
- یک کَش جدید ساخته میشود. این کش از کشهای دیگر که تا الان ساخته شدهاند مجزا است.
- از کش درخواست یک اتصال جدید میشود. در نتیجه یک جفت چنل ارسال و دریافت برمیگردد.
- با کمک اتصال خود میتوانیم به کش دستور دهیم، مثلاً یک کلید و مقدار دهیم تا ذخیره شود.
- با کمک همین اتصال یا اتصالات دیگر میتوانیم با داشتن کلید خود، مقدار را به دست بیاوریم.
به جز Get
و Set
که قابلیتهای اولیهی یک حافظهی نهان هستند، یک عملیات دیگر نیز تعریف میشود به نام SetWithRTL
که در اینجا RTL مخفف Request to Live است. این عدد برای هر کلید تعریف میشود و به معنی تعداد درخواستهای خواندن است که پس از ذخیره شدن مقدار آن کلید میتوانیم انجام دهیم تا نهایتاً آن کلید حذف شود. برای نمونه اگر یک RTL برابر با ۳ داشته باشیم، چنین اتفاقی میتواند بیفتد: پس از ۳ بار خواندن، آن مقدار از حافظه حذف شده است، بهگونهای که اصلاً وجود نداشته.
client: Set my_key my_val 3
client: Get my_key
server: my_val
client: Get my_key
server: my_val
client: Get my_key
server: my_val
client: Get my_key
server:
جزئیات پروژه
پروژهی اولیه را از این لینک دانلود کنید. ساختار فایلهای پروژه به صورت زیر است:
cache/
├── go.mod
├── go.sum
├── main.go
├── cache.go
└── main_sample_test.go
در فایل cache.go
چند تابع وجود دارد که در main.go
استفاده شدهاند و شما باید آنها را کامل کنید.
در فایل main.go
که نمیتوانید محتوای آن را تغییر دهید، پیادهسازی سمت کاربر این حافظهی نهان آمده است و در فایل تست نمونه، نحوه استفاده از آن آمده است.
در فایل cache.go
فقط امضای توابع آمدهاند. شما باید مطابق خواستهی صورت سؤال توابع را کامل کرده و در صورت نیاز توابع جدید اضافه کنید.
فایل main.go
func (conn *CacheClientConnection) Set(key string, val CacheVal) {
}
func (conn *CacheClientConnection) SetWithRTL(key string, val CacheVal, RTL int) {
}
func (conn *CacheClientConnection) Get(key string) CacheVal {
}
در این فایل همهی توابع پیادهسازی شدهاند و بر اساس این پیادهسازیها پروتوکل ارتباط بین کلاینت و سرور را مشاهده خواهید کرد. برای مثال، در صورتی که برای کلید مقداری وجود نداشته باشد، رشتهی خالی برمیگردد.
فایل cache.go
type Cache struct {
}
type CacheServerConnection struct {
}
func InitCache() *Cache {
// TODO
return nil
}
func (cache *Cache) Connect(name string) *CacheClientConnection {
}
تابع InitCache
در این تابع یک کش جدید ساخته شده و مقدار میگیرد و اشارهگر به آن برمیگردد. همچنین در صورت نیاز میتواند عملیات دیگری نیز انجام شود.
تابع Connect
در این قسمت یک کاربر جدید با یک نام جدید (که تضمین میشود یکتاست) میخواهد به این کش متصل شود. برای این منظور یک جفت چنل درست میشود که در قالب یک CacheClientConnection
به کاربر برمیگردد. همچنین باید این دو چنل برای خود کش نیز نگه داشته شوند تا بتوان به آنها گوش داد.
آنچه باید آپلود کنید
پس از پیادهسازی توابع خواستهشده، فایل cache.go
را آپلود کنید.
ارسال پاسخ برای این سؤال