Skip to content

[DP-103] Race condition in call #198

Closed
@qnikst

Description

@qnikst

[Imported from JIRA. Reported by Facundo Dominguez @facundominguez) as DP-103 on 2015-02-20 18:27:36]
By Facundo Dominguez at https://cloud-haskell.atlassian.net/browse/DP-103

The implementation of call [1] contains a text like the following:

-- We are guaranteed to receive the reply before the monitor notification
-- (if a reply is sent at all)

As discussed in https://cloud-haskell.atlassian.net/browse/DP-99 this is not true, and I have hit the case in practice where call fails with "call: remote process died: DiedNormal", because the monitor notification arrives before the response.

I don't know how to fix it yet. Maybe using a call to cpDelay after cpSend:

spawnMonitor nid (proc `bindCP` cpSend dict us `bindCP` cpDelay us (cpReturn ()))

and having call send () after unmonitoring.

[1]

call dict nid proc = do
us <- getSelfPid
(pid, mRef) <- spawnMonitor nid (proc `bindCP` cpSend dict us)
-- We are guaranteed to receive the reply before the monitor notification
-- (if a reply is sent at all)
-- NOTE: This might not be true if we switch to unreliable delivery.
mResult <- receiveWait
[ match (return . Right)
, matchIf (\(ProcessMonitorNotification ref _ _) -> ref == mRef)
(\(ProcessMonitorNotification _ _ reason) -> return (Left reason))
]
case mResult of
Right a -> do
-- Wait for the monitor message so that we the mailbox doesn't grow
receiveWait
[ matchIf (\(ProcessMonitorNotification ref _ _) -> ref == mRef)
(\(ProcessMonitorNotification {}) -> return ())
]
-- Clean up connection to pid
reconnect pid
return a
Left err ->
fail $ "call: remote process died: " ++ show err

Fixed by #183

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions