minio/cmd/notify-listener.go
Aditya Manthramurthy c3bbadacbf Improve Peer RPC error handling (Fixes #2992) (#2995)
* Check for RPC connection shutdown and try again just once.

* Refactor SendRPC to use sync.WaitGroup
2016-10-18 21:26:58 -07:00

94 lines
2.2 KiB
Go

/*
* Minio Cloud Storage, (C) 2016 Minio, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cmd
import (
"fmt"
"io/ioutil"
"net/rpc"
"github.com/Sirupsen/logrus"
)
type listenerConn struct {
TargetAddr string
ListenerARN string
}
type listenerLogger struct {
log *logrus.Logger
lconn listenerConn
}
func newListenerLogger(listenerArn, targetAddr string) (*listenerLogger, error) {
if globalS3Peers.GetPeerClient(targetAddr) == nil {
return nil, fmt.Errorf(
"Peer %s was not initialized - bug!",
targetAddr,
)
}
lc := listenerConn{
TargetAddr: targetAddr,
ListenerARN: listenerArn,
}
lcLog := logrus.New()
lcLog.Out = ioutil.Discard
lcLog.Formatter = new(logrus.JSONFormatter)
lcLog.Hooks.Add(lc)
return &listenerLogger{lcLog, lc}, nil
}
// send event to target server via rpc client calls.
func (lc listenerConn) Fire(entry *logrus.Entry) error {
notificationEvent, ok := entry.Data["Records"].([]NotificationEvent)
if !ok {
// If the record is not of the expected type, silently
// discard.
return nil
}
// Fetch peer client object
client := globalS3Peers.GetPeerClient(lc.TargetAddr)
if client == nil {
return fmt.Errorf("Target %s client RPC object not available!", lc.TargetAddr)
}
// Send Event RPC call and return error
arg := EventArgs{Event: notificationEvent, Arn: lc.ListenerARN}
reply := GenericReply{}
err := client.Call("S3.Event", &arg, &reply)
// In case connection is shutdown, retry once.
if err != nil {
if err.Error() == rpc.ErrShutdown.Error() {
err = client.Call("S3.Event", &arg, &reply)
}
}
return err
}
func (lc listenerConn) Levels() []logrus.Level {
return []logrus.Level{
logrus.InfoLevel,
}
}