Merge pull request #1145 from HaoZeke/socketPoller

ENH: Allow driver clients to poll for input
This commit is contained in:
Edoardo Aprà 2025-08-19 10:08:29 -07:00 committed by GitHub
commit 4c48fa339e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 108 additions and 39 deletions

View file

@ -29,6 +29,7 @@ c
double precision ascale, bscale, tscale, hscale
logical ignore,diagh
integer mh,ind
integer max_retries,retry_delay
* **** external functions ****
logical driver_parse_boolean
@ -98,7 +99,7 @@ c
$ mt_log,1,diagh))
$ call errquit('driver_input: rtdb put failed',0, RTDB_ERR)
c
c socket ipi_client ip:port
c socket ipi_client ip:port [retries <int>] [delay <int>]
c
else if (inp_compare(.false.,'socket', field)) then
if (inp_a(f2)) then
@ -114,6 +115,7 @@ c
> ipname(1:ind)))
> call errquit('driver_input: rtdb put failed',8,RTDB_ERR)
end if
diagh = .true.
if (.not. rtdb_put(rtdb,'driver:socket',
$ mt_log,1,diagh))
@ -127,7 +129,24 @@ c
$ mt_log,1,diagh))
$ call errquit('driver_input: rtdb put failed',0, RTDB_ERR)
end if
end if
do while (inp_a(field))
if (inp_compare(.false.,'retries',field)) then
if (.not. inp_i(max_retries)) call errquit(
& 'driver_input: expected integer for retries',0,
& INPUT_ERR)
if (.not. rtdb_put(rtdb,'driver:socket_retries',
& mt_int,1,max_retries)) call errquit(
& 'driver_input: rtdb put failed',10,RTDB_ERR)
else if (inp_compare(.false.,'delay',field)) then
if (.not. inp_i(retry_delay)) call errquit(
& 'driver_input: expected int for delay',0,
& INPUT_ERR)
if (.not. rtdb_put(rtdb,'driver:socket_delay',
& mt_int,1,retry_delay)) call errquit(
& 'driver_input: rtdb put failed',11,RTDB_ERR)
end if
end do
end if
c
else if (inp_compare(.false.,'deloc', field)) then
if (.not. rtdb_put(rtdb,'driver:deloc',mt_log,1,.true.))

View file

@ -25,6 +25,7 @@
integer rion(2),fion(2),nion,nion0
real*8 unita(3,3),invunita(3,3),stress(3,3),energy
real*8 cpu1,cpu2
integer max_retries, retry_delay_seconds
* **** external functions ****
logical task_gradient
@ -100,13 +101,23 @@
statebuffer(1:13) = "READY "
if (.not. rtdb_get(rtdb, 'driver:socket_retries', mt_int, 1,
> max_retries)) then
max_retries = 30
end if
if (.not. rtdb_get(rtdb, 'driver:socket_delay', mt_int, 1,
> retry_delay_seconds)) then
retry_delay_seconds = 2
end if
if (taskid.eq.MASTER) then
write(luout,*)
write(luout,*) "== i-PI Socket Client Driver =="
write(luout,'(" Connected to = ",A)') socket_ip
write(luout,'(" Number of atoms =",I8)') nion
write(luout,*)
call util_talker(ip,inet,ii-1,port,sock)
call util_talker(ip,inet,ii-1,port,sock,max_retries,
> retry_delay_seconds)
write(luout,*)
!call nwpw_talker("127.0.0.1",9,port,sock)
end if

View file

@ -14,67 +14,106 @@
#endif
#include "typesf2c.h"
void FATR util_talker_(char addr_name[], Integer * inet, Integer * n1, Integer * portin, Integer * sockout)
void FATR util_talker_(char addr_name[], Integer * inet, Integer * n1, Integer * portin, Integer * sockout, Integer * max_retries_in, Integer * retry_delay_seconds_in)
{
#if defined(__MINGW32__)
perror("util_talker: not coded for this architecture");
exit(1);
#else
int sock = 0, valread;
int na = ((int) *n1);
int sock = 0;
int max_retries = ((int) *max_retries_in);
int retry_delay_seconds = ((int) *retry_delay_seconds_in);
int retries = 0;
addr_name[na] = 0;
addr_name[na+1] = 0;
if (max_retries <= 0){
perror("Got an invalid (<=0) number of retries, resetting to 30\n");
max_retries = 30;
}
if (retry_delay_seconds <= 0){
perror("Got an invalid (<=0) delay for retries, resetting to 2\n");
retry_delay_seconds = 2;
}
if (*inet>0)
if (*inet > 0)
{
struct sockaddr_in serv_addr;
// --- TCP/IP Socket Logic ---
struct sockaddr_in serv_addr;
int port = ((int) *portin);
int na = ((int) *n1);
char addr_name_buf[256]; // Use a safe buffer
strncpy(addr_name_buf, addr_name, na);
addr_name_buf[na] = '\0';
printf("util_talker: addr_name=%s\n",addr_name);
printf("util_talker: port=%d\n",port);
printf("util_talker: Attempting to connect to TCP server %s:%d\n", addr_name_buf, port);
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\nutil_talker:Socket creation error \n");
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("util_talker: TCP socket creation error");
exit(1);
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(port);
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(port);
// Convert IPv4 and IPv6 addresses from text to binary form
if(inet_pton(AF_INET, addr_name, &serv_addr.sin_addr)<=0)
{
printf("\nutil_talker:Invalid address/ Address not supported \n");
if(inet_pton(AF_INET, addr_name_buf, &serv_addr.sin_addr) <= 0)
{
printf("\nutil_talker: Invalid address/Address not supported\n");
exit(1);
}
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\nutil_talker:Connection Failed \n");
exit(1);
}
}
// --- Retry Loop for TCP ---
while (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
if (++retries >= max_retries) {
fprintf(stderr, "\nutil_talker: TCP connection failed after %d attempts: %s. Exiting.\n", max_retries, strerror(errno));
exit(1);
}
printf("util_talker: Connection failed. Retrying in %d second(s)... (%d/%d)\n",
retry_delay_seconds, retries, max_retries);
sleep(retry_delay_seconds);
}
}
else
{
// --- UNIX Domain Socket Logic ---
struct sockaddr_un serv_addr;
int na = ((int)*n1);
char addr_name_buf[256];
strncpy(addr_name_buf, addr_name, na);
addr_name_buf[na] = '\0';
memset(&serv_addr, 0, sizeof(struct sockaddr_un));
serv_addr.sun_family = AF_UNIX;
strcpy(serv_addr.sun_path, "/tmp/ipi_");
strcpy(serv_addr.sun_path+9, addr_name);
if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
{
printf("\nutil_talker:Socket creation error \n");
// Construct the full socket path, same as the server
snprintf(serv_addr.sun_path, sizeof(serv_addr.sun_path), "/tmp/ipi_%s",
addr_name_buf);
printf("util_talker: Attempting to connect to UNIX socket %s\n",
serv_addr.sun_path);
if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
perror("util_talker: UNIX socket creation error");
exit(1);
}
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\nutil_talker:Failed to connect to UNIX socket \n");
exit(1);
// --- Retry Loop for UNIX ---
while (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) <
0) {
if (++retries >= max_retries) {
fprintf(stderr,
"\nutil_talker: UNIX socket connection failed after %d "
"attempts: %s. Exiting.\n",
max_retries, strerror(errno));
exit(1);
}
printf("util_talker: Connection failed. Retrying in %d second(s)... (%d/%d)\n",
retry_delay_seconds, retries, max_retries);
sleep(retry_delay_seconds);
}
}
printf("util_talker: sockid=%d\n",sock);
*sockout = ((Integer) sock);
printf("util_talker: Connection successful! Socket ID: %d\n", sock);
*sockout = ((Integer)sock);
#endif
}