2013-10-13 33 views
1

我有以下非常簡單的代碼來保留datastore中的字符串。我已經從各種datastore的例子中把它拉到一起,但我仍然對它不滿意。數據存儲的持久性是後面的一個

它的目的只是將一個字符串存儲在persist的一個密鑰下並在fromPresistence下檢索它。

// Used to store the string value. 
type Entity struct { 
    Value string 
} 

// Grow my key. 
func key(x string) *datastore.Key { 
    return datastore.NewKey(context, "Persist", x, 0, nil) 
} 

// Get it from persistence storage. 
func fromPersistence(x string) string { 
    var persisted string = x 
    // Make my key. 
    k := key(x) 
    // New entity for filling in. 
    e := new(Entity) 
    // Look it up! 
    if err := datastore.Get(context, k, e); err == nil { 
     // It was there! 
     persisted = e.Value 
     context.Debugf("Persisted %s=%s", x, persisted) 
    } 

    return persisted 
} 

// Persist the latest number. 
func persist(x string) func(*big.Int) { 
    return func(n *big.Int) { 
     // Make my key. 
     k := key(x) 
     // New entity for filling in. 
     e := new(Entity) 
     // Value is the decimal form of the number. 
     e.Value = n.String() 
     context.Debugf("Persist %s=%s", start, e.Value) 
     if _, err := datastore.Put(context, k, e); err != nil { 
      context.Debugf("Persist failed! %s", err) 
     } 
    } 
} 

但是它似乎每次都落後一次。下面是一些日誌結果:

C:\Go\GAE\go_appengine\google\src>\go\gae\go_appengine\dev_appserver.py unique/ 
INFO  2013-10-15 20:55:08,296 sdk_update_checker.py:245] Checking for updates to the SDK. 
INFO  2013-10-15 20:55:09,726 api_server.py:138] Starting API server at: http://localhost:50218 
INFO  2013-10-15 20:55:09,746 dispatcher.py:168] Starting module "default" running at: http://localhost:8080 
INFO  2013-10-15 20:55:09,763 admin_server.py:117] Starting admin server at: http://localhost:8000 
INFO  2013-10-15 20:56:22,131 module.py:599] default: "GET/HTTP/1.1" 304 - 
INFO  2013-10-15 20:56:22,344 module.py:599] default: "GET /favicon.ico HTTP/1.1" 304 - 
INFO  2013-10-15 20:56:22,448 module.py:599] default: "GET /favicon.ico HTTP/1.1" 304 - 
2013/10/15 20:56:26 DEBUG: Persisted 38913371956013078496870267859=3378577588146889866220112993 
2013/10/15 20:56:26 DEBUG: Persist 38913371956013078496870267859=21186844412818184262771263024 
... 
2013/10/15 20:56:30 DEBUG: Persist 38913371956013078496870267859=1324177775801136516423203939 
INFO  2013-10-15 20:56:30,756 module.py:599] default: "GET /n HTTP/1.1" 200 19 
INFO  2013-10-15 20:56:30,927 module.py:599] default: "GET /favicon.ico HTTP/1.1" 304 - 
2013/10/15 20:56:32 DEBUG: Persist 38913371956013078496870267859=20778614526287997725322370609 

C:\Go\GAE\go_appengine\google\src>\go\gae\go_appengine\dev_appserver.py unique/ 
INFO  2013-10-15 20:57:15,657 sdk_update_checker.py:245] Checking for updates to the SDK. 
INFO  2013-10-15 20:57:17,033 api_server.py:138] Starting API server at: http://localhost:50241 
INFO  2013-10-15 20:57:17,085 dispatcher.py:168] Starting module "default" running at: http://localhost:8080 
INFO  2013-10-15 20:57:17,098 admin_server.py:117] Starting admin server at: http://localhost:8000 
2013/10/15 20:57:24 DEBUG: Persisted 38913371956013078496870267859=1324177775801136516423203939 
2013/10/15 20:57:24 DEBUG: Persist 38913371956013078496870267859=20778614526287997725322370609 
... 

看到持久性存儲最後一次嘗試,但檢索嘗試如何返回的先前堅持的價值。

我在做什麼錯?

注意:我已更改代碼以使用context.Debugf機制來打印我的調試字符串以獲取等式中的奇怪日誌記錄。

舊的Logf代碼如下。我確定這是奇怪日誌條目的原因。這不是我的問題的目標。我會自己解決這個問題。

func Logf(format string, a ...interface{}) { 
    if context != nil { 
     // Context is valid. 
     if len(logQueue) > 0 { 
      // Roll out the stored entries. 
      for i := 0; i < len(logQueue); i++ { 
       context.Debugf("%s", logQueue[i]) 
      } 
      // Empty the queue. 
      logQueue = make([]string, 0) 
     } 
     // Pass a "" to just flush the queue 
     if format != "" { 
      // Log it through the context. 
      context.Debugf(format, a) 
     } 
    } else { 
     // No context! Queue it up. 
     logQueue = append(logQueue, fmt.Sprintf(format, a...)) 
    } 

} 
+0

這些都是不一樣的打印語句。沒有「[]」 – stark

+0

我知道這聽起來像一個愚蠢的問題,但你是否在任何地方使用基於'1'的索引?這只是*感覺*就像它從切片中拉出錯誤的值,並且索引被關閉。也許在'NewKey'函數中? – Intermernet

+0

我打算晚些時候發佈我的'Logf'函數來消除在這裏發生切片/數組的想法。我確信格式化和「MISSING」註釋純粹是一種紅鯡魚。請注意,該鍵總是'x string',並且返回的值始終是'string'。 – OldCurmudgeon

回答

0

這裏有一個很好的 機會 ,你看到的是分佈式系統中那些意想不到的方面之一。如果您對persistfromPersistence的調用最終在應用程序的不同實例上運行,那麼日誌消息可能會略有不同,以至它們持續存在的位置。請注意,看似相反的日誌消息上的時間戳是相同的。

+0

Logf系統可能會延遲記錄的實際記錄,直到有一個Context可用於記錄。時間戳因此不可靠。有趣的想法,但。然而,我懷疑這不是一個時間問題 - 每次都會持續發生滯後。 – OldCurmudgeon

+0

我現在已經確認在活動網站上發生同樣的問題 - 不只是在本地模擬器中。我不認爲我看到不同的線程/實例 - 我希望只偶爾顯示,我每**時間看到它**。 – OldCurmudgeon

0

看看你的數據存儲區代碼......它以某種方式將值存儲在鍵中。

Logf("Persist %s=%s", x, e.Value)

正在生產的語句:

2013/10/13 23:21:26 DEBUG: Persist [38913371956013078496870267859 19124562091635092830747528895]=%s(MISSING)

,這意味着你的「X」值存在的關鍵和其他一些值的一部分(從你的文字又好像是以前的鍵值)。

實際值丟失......這是什麼%s(MISSING)位意味着

+0

好點,但我推斷...... MISSING的東西只是我不熟悉'fmt'。這些功能正常工作 - 唯一的問題是始終存在一次進入滯後。 「Persist」和「Persisted」記錄相同的事實表明,它甚至可能是我的錯誤記錄機制。 – OldCurmudgeon

+0

我會更正日誌記錄系統,以便在依靠它來診斷系統的另一部分之前從中獲得可靠的答案。 當你記錄的日誌功能被破壞的時候,你很難看到你的單一滯後來自何處,你的保證如果它顯然不是有效的,那麼「它正常工作」 ) – mfhholmes

+0

只是爲了澄清:e.Value中對於每種情況的實際內容是什麼?你的日誌函數說它是MISSING,而你返回的鍵值是字符串切片。當可用信息如此混亂時,很難看到發生了什麼;) 您是否爲這個功能編寫過任何測試用例? – mfhholmes