Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions pkg/call/service/call_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ type RejectCallStruct struct {
}

func (c *callService) ensureClientConnected(instanceId string) (*whatsmeow.Client, error) {
whatsmeow_service.ClientMapsMu.RLock()
client := c.clientPointer[instanceId]
whatsmeow_service.ClientMapsMu.RUnlock()
c.loggerWrapper.GetLogger(instanceId).LogInfo("[%s] Checking client connection status - Client exists: %v", instanceId, client != nil)

if client == nil {
Expand All @@ -43,7 +45,9 @@ func (c *callService) ensureClientConnected(instanceId string) (*whatsmeow.Clien
c.loggerWrapper.GetLogger(instanceId).LogInfo("[%s] Instance started, waiting 2 seconds...", instanceId)
time.Sleep(2 * time.Second)

whatsmeow_service.ClientMapsMu.RLock()
client = c.clientPointer[instanceId]
whatsmeow_service.ClientMapsMu.RUnlock()
c.loggerWrapper.GetLogger(instanceId).LogInfo("[%s] Checking new client - Exists: %v, Connected: %v",
instanceId,
client != nil,
Expand Down
4 changes: 4 additions & 0 deletions pkg/chat/service/chat_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ type HistorySyncRequestStruct struct {
}

func (c *chatService) ensureClientConnected(instanceId string) (*whatsmeow.Client, error) {
whatsmeow_service.ClientMapsMu.RLock()
client := c.clientPointer[instanceId]
whatsmeow_service.ClientMapsMu.RUnlock()
c.loggerWrapper.GetLogger(instanceId).LogInfo("[%s] Checking client connection status - Client exists: %v", instanceId, client != nil)

if client == nil {
Expand All @@ -54,7 +56,9 @@ func (c *chatService) ensureClientConnected(instanceId string) (*whatsmeow.Clien
c.loggerWrapper.GetLogger(instanceId).LogInfo("[%s] Instance started, waiting 2 seconds...", instanceId)
time.Sleep(2 * time.Second)

whatsmeow_service.ClientMapsMu.RLock()
client = c.clientPointer[instanceId]
whatsmeow_service.ClientMapsMu.RUnlock()
c.loggerWrapper.GetLogger(instanceId).LogInfo("[%s] Checking new client - Exists: %v, Connected: %v",
instanceId,
client != nil,
Expand Down
4 changes: 4 additions & 0 deletions pkg/community/service/community_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ type AddParticipantStruct struct {
}

func (c *communityService) ensureClientConnected(instanceId string) (*whatsmeow.Client, error) {
whatsmeow_service.ClientMapsMu.RLock()
client := c.clientPointer[instanceId]
whatsmeow_service.ClientMapsMu.RUnlock()
c.loggerWrapper.GetLogger(instanceId).LogInfo("[%s] Checking client connection status - Client exists: %v", instanceId, client != nil)

if client == nil {
Expand All @@ -50,7 +52,9 @@ func (c *communityService) ensureClientConnected(instanceId string) (*whatsmeow.
c.loggerWrapper.GetLogger(instanceId).LogInfo("[%s] Instance started, waiting 2 seconds...", instanceId)
time.Sleep(2 * time.Second)

whatsmeow_service.ClientMapsMu.RLock()
client = c.clientPointer[instanceId]
whatsmeow_service.ClientMapsMu.RUnlock()
c.loggerWrapper.GetLogger(instanceId).LogInfo("[%s] Checking new client - Exists: %v, Connected: %v",
instanceId,
client != nil,
Expand Down
4 changes: 4 additions & 0 deletions pkg/group/service/group_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,9 @@ type UpdateGroupRequestParticipantsStruct struct {
}

func (g *groupService) ensureClientConnected(instanceId string) (*whatsmeow.Client, error) {
whatsmeow_service.ClientMapsMu.RLock()
client := g.clientPointer[instanceId]
whatsmeow_service.ClientMapsMu.RUnlock()
g.loggerWrapper.GetLogger(instanceId).LogInfo("[%s] Checking client connection status - Client exists: %v", instanceId, client != nil)

if client == nil {
Expand All @@ -131,7 +133,9 @@ func (g *groupService) ensureClientConnected(instanceId string) (*whatsmeow.Clie
g.loggerWrapper.GetLogger(instanceId).LogInfo("[%s] Instance started, waiting 2 seconds...", instanceId)
time.Sleep(2 * time.Second)

whatsmeow_service.ClientMapsMu.RLock()
client = g.clientPointer[instanceId]
whatsmeow_service.ClientMapsMu.RUnlock()
g.loggerWrapper.GetLogger(instanceId).LogInfo("[%s] Checking new client - Exists: %v, Connected: %v",
instanceId,
client != nil,
Expand Down
106 changes: 86 additions & 20 deletions pkg/instance/service/instance_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,9 @@ type ForceReconnectStruct struct {

func (i *instances) ensureClientConnected(instanceId string) (*whatsmeow.Client, error) {
logger := i.loggerWrapper.GetLogger(instanceId)
whatsmeow_service.ClientMapsMu.RLock()
client := i.clientPointer[instanceId]
whatsmeow_service.ClientMapsMu.RUnlock()
logger.LogInfo("[%s] Checking client connection status - Client exists: %v", instanceId, client != nil)

if client == nil {
Expand All @@ -138,7 +140,9 @@ func (i *instances) ensureClientConnected(instanceId string) (*whatsmeow.Client,
logger.LogInfo("[%s] Instance started, waiting 2 seconds...", instanceId)
time.Sleep(2 * time.Second)

whatsmeow_service.ClientMapsMu.RLock()
client = i.clientPointer[instanceId]
whatsmeow_service.ClientMapsMu.RUnlock()
logger.LogInfo("[%s] Checking new client - Exists: %v, Connected: %v",
instanceId,
client != nil,
Expand Down Expand Up @@ -242,7 +246,9 @@ func (i instances) Connect(data *ConnectStruct, instance *instance_model.Instanc
}

// Verifica se a instância já está rodando
whatsmeow_service.ClientMapsMu.RLock()
isInstanceRunning := i.clientPointer[instance.Id] != nil
whatsmeow_service.ClientMapsMu.RUnlock()

// Sincroniza as configurações na instância em execução (se já estiver conectada)
err = i.whatsmeowService.UpdateInstanceSettings(instance.Id)
Expand All @@ -258,7 +264,9 @@ func (i instances) Connect(data *ConnectStruct, instance *instance_model.Instanc
if !isInstanceRunning {
i.loggerWrapper.GetLogger(instance.Id).LogInfo("[%s] Starting new client instance", instance.Id)

whatsmeow_service.ClientMapsMu.Lock()
i.killChannel[instance.Id] = make(chan bool)
whatsmeow_service.ClientMapsMu.Unlock()

clientData := &whatsmeow_service.ClientData{
Instance: instance,
Expand Down Expand Up @@ -317,7 +325,10 @@ func (i instances) Disconnect(instance *instance_model.Instance) (*instance_mode
if client.IsConnected() {
if client.IsLoggedIn() {
i.loggerWrapper.GetLogger(instance.Id).LogInfo("[%s] Disconnection successful", instance.Id)
i.killChannel[instance.Id] <- true
whatsmeow_service.ClientMapsMu.RLock()
killChan := i.killChannel[instance.Id]
whatsmeow_service.ClientMapsMu.RUnlock()
killChan <- true

instance.Events = ""

Expand Down Expand Up @@ -352,13 +363,18 @@ func (i instances) Logout(instance *instance_model.Instance) (*instance_model.In
return instance, err
}

whatsmeow_service.ClientMapsMu.RLock()
logoutKillChan := i.killChannel[instance.Id]
whatsmeow_service.ClientMapsMu.RUnlock()
select {
case i.killChannel[instance.Id] <- true:
case logoutKillChan <- true:
case <-time.After(5 * time.Second):
}

whatsmeow_service.ClientMapsMu.Lock()
delete(i.clientPointer, instance.Id)
delete(i.killChannel, instance.Id)
whatsmeow_service.ClientMapsMu.Unlock()

i.loggerWrapper.GetLogger(instance.Id).LogInfo("[%s] Logout successful", instance.Id)
return instance, nil
Expand All @@ -367,13 +383,18 @@ func (i instances) Logout(instance *instance_model.Instance) (*instance_model.In
if client.IsConnected() {
client.Disconnect()

whatsmeow_service.ClientMapsMu.RLock()
disconnectKillChan := i.killChannel[instance.Id]
whatsmeow_service.ClientMapsMu.RUnlock()
select {
case i.killChannel[instance.Id] <- true:
case disconnectKillChan <- true:
case <-time.After(5 * time.Second):
}

whatsmeow_service.ClientMapsMu.Lock()
delete(i.clientPointer, instance.Id)
delete(i.killChannel, instance.Id)
whatsmeow_service.ClientMapsMu.Unlock()

i.loggerWrapper.GetLogger(instance.Id).LogInfo("[%s] Disconnection successful", instance.Id)
return instance, nil
Expand All @@ -384,7 +405,9 @@ func (i instances) Logout(instance *instance_model.Instance) (*instance_model.In
}

func (i instances) Status(instance *instance_model.Instance) (*StatusStruct, error) {
whatsmeow_service.ClientMapsMu.RLock()
client := i.clientPointer[instance.Id]
whatsmeow_service.ClientMapsMu.RUnlock()

if client == nil {
return &StatusStruct{
Expand Down Expand Up @@ -413,7 +436,9 @@ func (i instances) Status(instance *instance_model.Instance) (*StatusStruct, err

func (i instances) GetQr(instance *instance_model.Instance) (*QrcodeStruct, error) {
logger := i.loggerWrapper.GetLogger(instance.Id)
whatsmeow_service.ClientMapsMu.RLock()
client := i.clientPointer[instance.Id]
whatsmeow_service.ClientMapsMu.RUnlock()

// Se não há cliente ou o cliente está logado, precisamos iniciar um novo cliente
if client == nil || client.IsLoggedIn() {
Expand All @@ -435,7 +460,9 @@ func (i instances) GetQr(instance *instance_model.Instance) (*QrcodeStruct, erro
time.Sleep(3 * time.Second)

// Verificar novamente se há cliente
whatsmeow_service.ClientMapsMu.RLock()
client = i.clientPointer[instance.Id]
whatsmeow_service.ClientMapsMu.RUnlock()
if client != nil && client.IsLoggedIn() {
return nil, fmt.Errorf("session already logged in")
}
Expand Down Expand Up @@ -511,7 +538,9 @@ func buildPasskeyOpenURL(token string) string {

func (i instances) Pair(data *PairStruct, instance *instance_model.Instance) (*PairReturnStruct, error) {
logger := i.loggerWrapper.GetLogger(instance.Id)
whatsmeow_service.ClientMapsMu.RLock()
client := i.clientPointer[instance.Id]
whatsmeow_service.ClientMapsMu.RUnlock()

if client == nil || !client.IsConnected() {
if client != nil && client.IsLoggedIn() {
Expand All @@ -525,7 +554,9 @@ func (i instances) Pair(data *PairStruct, instance *instance_model.Instance) (*P
// Wait for the WA websocket connection and initial QR generation to establish.
// PairPhone must be called after the QR event is received per whatsmeow docs.
time.Sleep(3 * time.Second)
whatsmeow_service.ClientMapsMu.RLock()
client = i.clientPointer[instance.Id]
whatsmeow_service.ClientMapsMu.RUnlock()
if client == nil {
return nil, fmt.Errorf("failed to initialize client for pairing")
}
Expand All @@ -551,7 +582,10 @@ func (i instances) GetAll() ([]*instance_model.Instance, error) {
}

for _, instance := range instances {
if client := i.clientPointer[instance.Id]; client != nil {
whatsmeow_service.ClientMapsMu.RLock()
client := i.clientPointer[instance.Id]
whatsmeow_service.ClientMapsMu.RUnlock()
if client != nil {
instance.Connected = client.IsLoggedIn()
} else {
instance.Connected = false
Expand All @@ -570,7 +604,10 @@ func (i instances) Info(instanceId string) (*instance_model.Instance, error) {
}

// Atualiza o status connected com base no estado real do cliente
if client := i.clientPointer[instance.Id]; client != nil {
whatsmeow_service.ClientMapsMu.RLock()
client := i.clientPointer[instance.Id]
whatsmeow_service.ClientMapsMu.RUnlock()
if client != nil {
instance.Connected = client.IsLoggedIn()
} else {
instance.Connected = false
Expand All @@ -587,19 +624,31 @@ func (i instances) Delete(id string) error {
return err
}

if i.clientPointer[instance.Id] != nil && i.clientPointer[instance.Id].IsConnected() {
if i.clientPointer[instance.Id].IsLoggedIn() {
i.clientPointer[instance.Id].Logout(context.Background())
whatsmeow_service.ClientMapsMu.RLock()
deleteClient := i.clientPointer[instance.Id]
whatsmeow_service.ClientMapsMu.RUnlock()

if deleteClient != nil && deleteClient.IsConnected() {
if deleteClient.IsLoggedIn() {
deleteClient.Logout(context.Background())
}
i.clientPointer[instance.Id].Disconnect()
deleteClient.Disconnect()
}

// Limpar todos os recursos da instância antes de deletar
// Limpar todos os recursos da instância antes de deletar. Read-then-delete
// on killChannel happens under the same Lock as the clientPointer delete so
// a concurrent Delete()/cleanup can't double-close the channel.
whatsmeow_service.ClientMapsMu.Lock()
delete(i.clientPointer, instance.Id)
if i.killChannel[instance.Id] != nil {
close(i.killChannel[instance.Id])
deleteKillChan := i.killChannel[instance.Id]
if deleteKillChan != nil {
delete(i.killChannel, instance.Id)
}
whatsmeow_service.ClientMapsMu.Unlock()

if deleteKillChan != nil {
close(deleteKillChan)
}

// Limpar cache via whatsmeow service
err = i.whatsmeowService.ClearInstanceCache(instance.Id, instance.Token)
Expand Down Expand Up @@ -697,7 +746,10 @@ func (i instances) RemoveProxy(id string) error {
}

func (i instances) ForceReconnect(instanceId string, number string) error {
if i.clientPointer[instanceId].IsConnected() && i.clientPointer[instanceId].IsLoggedIn() {
whatsmeow_service.ClientMapsMu.RLock()
forceReconnectClient := i.clientPointer[instanceId]
whatsmeow_service.ClientMapsMu.RUnlock()
if forceReconnectClient.IsConnected() && forceReconnectClient.IsLoggedIn() {
return fmt.Errorf("client already connected")
}

Expand All @@ -713,7 +765,9 @@ func (i instances) ForceReconnect(instanceId string, number string) error {

subscribedEvents := strings.Split(instance.Events, ",")

whatsmeow_service.ClientMapsMu.Lock()
i.killChannel[instance.Id] = make(chan bool)
whatsmeow_service.ClientMapsMu.Unlock()

clientData := &whatsmeow_service.ClientData{
Instance: instance,
Expand All @@ -735,29 +789,41 @@ func (i instances) ForceReconnect(instanceId string, number string) error {
}
}

if i.clientPointer[instance.Id] != nil {
client := i.clientPointer[instance.Id]
client.Disconnect()
whatsmeow_service.ClientMapsMu.RLock()
existingForceReconnectClient := i.clientPointer[instance.Id]
whatsmeow_service.ClientMapsMu.RUnlock()

if existingForceReconnectClient != nil {
existingForceReconnectClient.Disconnect()

whatsmeow_service.ClientMapsMu.RLock()
forceReconnectKillChan := i.killChannel[instance.Id]
whatsmeow_service.ClientMapsMu.RUnlock()
select {
case i.killChannel[instance.Id] <- true:
case forceReconnectKillChan <- true:
case <-time.After(5 * time.Second):
}

whatsmeow_service.ClientMapsMu.Lock()
delete(i.clientPointer, instance.Id)
delete(i.killChannel, instance.Id)
whatsmeow_service.ClientMapsMu.Unlock()
}

go i.whatsmeowService.StartClient(clientData)

time.Sleep(2 * time.Second)

if i.clientPointer[instance.Id] != nil {
if !i.clientPointer[instance.Id].IsConnected() {
whatsmeow_service.ClientMapsMu.RLock()
newForceReconnectClient := i.clientPointer[instance.Id]
whatsmeow_service.ClientMapsMu.RUnlock()

if newForceReconnectClient != nil {
if !newForceReconnectClient.IsConnected() {
return fmt.Errorf("failed to connect")
}

if !i.clientPointer[instance.Id].IsLoggedIn() {
if !newForceReconnectClient.IsLoggedIn() {
return fmt.Errorf("failed to login")
}
} else {
Expand Down
4 changes: 4 additions & 0 deletions pkg/label/service/label_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ type EditLabelStruct struct {
}

func (l *labelService) ensureClientConnected(instanceId string) (*whatsmeow.Client, error) {
whatsmeow_service.ClientMapsMu.RLock()
client := l.clientPointer[instanceId]
whatsmeow_service.ClientMapsMu.RUnlock()
l.loggerWrapper.GetLogger(instanceId).LogInfo("[%s] Checking client connection status - Client exists: %v", instanceId, client != nil)

if client == nil {
Expand All @@ -64,7 +66,9 @@ func (l *labelService) ensureClientConnected(instanceId string) (*whatsmeow.Clie
l.loggerWrapper.GetLogger(instanceId).LogInfo("[%s] Instance started, waiting 2 seconds...", instanceId)
time.Sleep(2 * time.Second)

whatsmeow_service.ClientMapsMu.RLock()
client = l.clientPointer[instanceId]
whatsmeow_service.ClientMapsMu.RUnlock()
l.loggerWrapper.GetLogger(instanceId).LogInfo("[%s] Checking new client - Exists: %v, Connected: %v",
instanceId,
client != nil,
Expand Down
4 changes: 4 additions & 0 deletions pkg/message/service/message_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,9 @@ type MessageSendStruct struct {
}

func (m *messageService) ensureClientConnected(instanceId string) (*whatsmeow.Client, error) {
whatsmeow_service.ClientMapsMu.RLock()
client := m.clientPointer[instanceId]
whatsmeow_service.ClientMapsMu.RUnlock()
m.loggerWrapper.GetLogger(instanceId).LogInfo("[%s] Checking client connection status - Client exists: %v", instanceId, client != nil)

if client == nil {
Expand All @@ -109,7 +111,9 @@ func (m *messageService) ensureClientConnected(instanceId string) (*whatsmeow.Cl
m.loggerWrapper.GetLogger(instanceId).LogInfo("[%s] Instance started, waiting 2 seconds...", instanceId)
time.Sleep(2 * time.Second)

whatsmeow_service.ClientMapsMu.RLock()
client = m.clientPointer[instanceId]
whatsmeow_service.ClientMapsMu.RUnlock()
m.loggerWrapper.GetLogger(instanceId).LogInfo("[%s] Checking new client - Exists: %v, Connected: %v",
instanceId,
client != nil,
Expand Down
Loading