Hi guys!
I know this is quite challenging, but it makes sense in io-heavy 
applications.

I need to test the responsiveness of different financial future quotation 
sources. They return the quotations spontaneously, and my program respond 
to each one of the CGO call backs from the quotation library and save the 
current prices. Meanwhile, a timer ensures to check the current quotations 
of each available sources. And obviously, it raised up a panic due to 
synchronization of maps on the call of ReadMaps function. Unfortunately 
this came up occasionally and `go build -race` cannot raise the problem.

Here is a piece of the code, only the read/write part:

------------------------------------------------------------------------------------------

// Please Ignore SyChan to alert the timer that all available sources are 
collected 
var SyChan chan int = make(chan int, 3)

// Make up a map of 5 mutex locks and a map of 5 data structs, indexed by 
1-5
var marketMaps = make(map[int]map[string]Market)
var mapLocks = make(map[int]*sync.Mutex)

// quotation data
type Market struct {
        Price     float64 `json:"price"`
        Timestamp string  `json:"timestamp"`
}

func init() {
        for i := 1; i <= 5; i++ {
                mapLocks[i] = new(sync.Mutex)
                marketMaps[i] = make(map[string]Market)
        }
}

//Make sure that for each source, R/W has no race, only took place as 
acquiring the particular Mutex inside the map of Mutex.
func RWMaps(targetnum int, purpose, future_id string, market Market) 
map[string]Market {
    
        mapLocks[targetnum].Lock()
        defer mapLocks[targetnum].Unlock()

        if purpose == "update" {//The original Write part
                marketMaps[targetnum][future_id] = market
                   return nil
        } else { //The read part, has been extracted to ReadMaps
                SyChan <- 1
                return marketMaps[targetnum]
        }
}

//Here is why I use map: not all 5 sources must be available, some may have 
connection failure and would be marked as false in Usable[i] , i being its 
source No.
func ReadMaps(targetnum, checkTime int) map[string]Market {
        mapLocks[targetnum].Lock()
        defer mapLocks[targetnum].Unlock()
        if Usable[targetnum] {
                fmt.Printf("%d-th time to read source %d \n", checkTime, 
targetnum)
        }
        SyChan <- 1
        return marketMaps[targetnum]
}

--------------------------------------------------------------------------------------------------

My problem is :

I still want to keep the map structure, rather than naming mutex1, mutex2, 
mutex3,... , marketmsg1, marketmsg2, .... And obviously if the map 
prohibits reading or writing spontaneously, the writing by each usable 
sources is not fair - They must line up as one queue (like using one Mutex 
for all instead) hence the checking of quotation snap on a time-spot is 
defected.  I have also checked the sync.Map and it seems to allow 
spontaneous reading but still prohibits spontaneous writing.

My instinct is to make map on the pointer of structs. On that way, if I 
could use sync.Map, both the read and write function only read the map to 
find the address of data structs, then writing several data structs on the 
same time won't violate the rule on sync.Map.

Is the proposal above legitimate? And anyone could come up a test case to 
mimic the quotation sources? Because with CGO to complicate the program, go 
cannot raise the race problem on -race check, and the successful build can 
panic occasionally.

Thanks in advance! 

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/9a981200-23f8-4dae-8c20-7acfdcd3f2fcn%40googlegroups.com.

Reply via email to