* Apply main loop. */
| 2164 | * Apply main loop. |
| 2165 | */ |
| 2166 | static void |
| 2167 | LogicalRepApplyLoop(XLogRecPtr last_received) |
| 2168 | { |
| 2169 | TimestampTz last_recv_timestamp = GetCurrentTimestamp(); |
| 2170 | bool ping_sent = false; |
| 2171 | TimeLineID tli; |
| 2172 | |
| 2173 | /* |
| 2174 | * Init the ApplyMessageContext which we clean up after each replication |
| 2175 | * protocol message. |
| 2176 | */ |
| 2177 | ApplyMessageContext = AllocSetContextCreate(ApplyContext, |
| 2178 | "ApplyMessageContext", |
| 2179 | ALLOCSET_DEFAULT_SIZES); |
| 2180 | |
| 2181 | /* |
| 2182 | * This memory context is used for per-stream data when the streaming mode |
| 2183 | * is enabled. This context is reset on each stream stop. |
| 2184 | */ |
| 2185 | LogicalStreamingContext = AllocSetContextCreate(ApplyContext, |
| 2186 | "LogicalStreamingContext", |
| 2187 | ALLOCSET_DEFAULT_SIZES); |
| 2188 | |
| 2189 | /* mark as idle, before starting to loop */ |
| 2190 | pgstat_report_activity(STATE_IDLE, NULL); |
| 2191 | |
| 2192 | /* This outer loop iterates once per wait. */ |
| 2193 | for (;;) |
| 2194 | { |
| 2195 | pgsocket fd = PGINVALID_SOCKET; |
| 2196 | int rc; |
| 2197 | int len; |
| 2198 | char *buf = NULL; |
| 2199 | bool endofstream = false; |
| 2200 | long wait_time; |
| 2201 | |
| 2202 | CHECK_FOR_INTERRUPTS(); |
| 2203 | |
| 2204 | MemoryContextSwitchTo(ApplyMessageContext); |
| 2205 | |
| 2206 | len = walrcv_receive(LogRepWorkerWalRcvConn, &buf, &fd); |
| 2207 | |
| 2208 | if (len != 0) |
| 2209 | { |
| 2210 | /* Loop to process all available data (without blocking). */ |
| 2211 | for (;;) |
| 2212 | { |
| 2213 | CHECK_FOR_INTERRUPTS(); |
| 2214 | |
| 2215 | if (len == 0) |
| 2216 | { |
| 2217 | break; |
| 2218 | } |
| 2219 | else if (len < 0) |
| 2220 | { |
| 2221 | ereport(LOG, |
| 2222 | (errmsg("data stream from publisher has ended"))); |
| 2223 | endofstream = true; |
no test coverage detected