Skip to content

Commit a676e6e

Browse files
authored
Merge pull request #152 from ControlCore-Project/dev
Merge dev to main
2 parents f6ed1c9 + 2df10f9 commit a676e6e

15 files changed

+812
-410
lines changed

.github/workflows/draft-pdf.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,16 @@ jobs:
66
name: Paper Draft
77
steps:
88
- name: Checkout
9-
uses: actions/checkout@v2
9+
uses: actions/checkout@v4
1010
- name: Build draft PDF
1111
uses: openjournals/openjournals-draft-action@master
1212
with:
1313
journal: joss
1414
# This should be the path to the paper within your repo.
1515
paper-path: paper.md
1616
- name: Upload
17-
uses: actions/upload-artifact@v1
17+
uses: actions/upload-artifact@v4
18+
1819
with:
1920
name: paper
2021
# This is the output path where Pandoc will write the compiled

Dockerfile.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
FROM openjdk:17-jdk-alpine
2+
3+
WORKDIR /app
4+
5+
# Only copy the JAR if it exists
6+
COPY ./target/concore-0.0.1-SNAPSHOT.jar /app/concore.jar || true
7+
8+
# Ensure the JAR file is executable if present
9+
RUN [ -f /app/concore.jar ] && chmod +x /app/concore.jar || true
10+
11+
EXPOSE 3000
12+
13+
# Run Java app only if the JAR exists, otherwise do nothing
14+
CMD ["/bin/sh", "-c", "if [ -f /app/concore.jar ]; then java -jar /app/concore.jar; else echo 'No Java application found, exiting'; fi"]

concore.py

Lines changed: 73 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,24 @@
1212
with open("concorekill.bat","w") as fpid:
1313
fpid.write("taskkill /F /PID "+str(os.getpid())+"\n")
1414

15-
try:
16-
iport = literal_eval(open("concore.iport").read())
17-
except:
18-
iport = dict()
19-
try:
20-
oport = literal_eval(open("concore.oport").read())
21-
except:
22-
oport = dict()
23-
15+
def safe_literal_eval(filename, defaultValue):
16+
try:
17+
with open(filename, "r") as file:
18+
return literal_eval(file.read())
19+
except (FileNotFoundError, SyntaxError, ValueError, Exception) as e:
20+
print(f"Error reading {filename}: {e}")
21+
return defaultValue
22+
23+
iport = safe_literal_eval("concore.iport", {})
24+
oport = safe_literal_eval("concore.oport", {})
2425

2526
s = ''
2627
olds = ''
2728
delay = 1
2829
retrycount = 0
2930
inpath = "./in" #must be rel path for local
3031
outpath = "./out"
32+
simtime = 0
3133

3234
#9/21/22
3335
try:
@@ -46,70 +48,92 @@
4648
except:
4749
params = dict()
4850
#9/30/22
49-
def tryparam(n,i):
50-
try:
51-
return params[n]
52-
except:
53-
return i
51+
def tryparam(n, i):
52+
return params.get(n, i)
5453

5554

5655
#9/12/21
5756
def default_maxtime(default):
5857
global maxtime
59-
try:
60-
maxtime = literal_eval(open(inpath+"1/concore.maxtime").read())
61-
except:
62-
maxtime = default
58+
maxtime = safe_literal_eval(os.path.join(inpath + "1", "concore.maxtime"), default)
59+
6360
default_maxtime(100)
6461

6562
def unchanged():
66-
global olds,s
67-
if olds==s:
63+
global olds, s
64+
if olds == s:
6865
s = ''
6966
return True
70-
else:
71-
olds = s
72-
return False
67+
olds = s
68+
return False
7369

7470
def read(port, name, initstr):
75-
global s,simtime,retrycount
71+
global s, simtime, retrycount
72+
max_retries=5
7673
time.sleep(delay)
74+
file_path = os.path.join(inpath+str(port), name)
75+
7776
try:
78-
infile = open(inpath+str(port)+"/"+name);
79-
ins = infile.read()
80-
infile.close()
81-
except:
77+
with open(file_path, "r") as infile:
78+
ins = infile.read()
79+
except FileNotFoundError:
80+
print(f"File {file_path} not found, using default value.")
8281
ins = initstr
83-
while len(ins)==0:
82+
except Exception as e:
83+
print(f"Error reading {file_path}: {e}")
84+
return initstr
85+
86+
attempts = 0
87+
while len(ins) == 0 and attempts < max_retries:
8488
time.sleep(delay)
85-
infile = open(inpath+str(port)+"/"+name);
86-
ins = infile.read()
87-
infile.close()
89+
try:
90+
with open(file_path, "r") as infile:
91+
ins = infile.read()
92+
except Exception as e:
93+
print(f"Retry {attempts + 1}: Error reading {file_path} - {e}")
94+
attempts += 1
8895
retrycount += 1
96+
97+
if len(ins) == 0:
98+
print(f"Max retries reached for {file_path}, using default value.")
99+
return initstr
100+
89101
s += ins
90-
inval = literal_eval(ins)
91-
simtime = max(simtime,inval[0])
92-
return inval[1:]
102+
try:
103+
inval = literal_eval(ins)
104+
simtime = max(simtime, inval[0])
105+
return inval[1:]
106+
except Exception as e:
107+
print(f"Error parsing {ins}: {e}")
108+
return initstr
109+
93110

94111
def write(port, name, val, delta=0):
95-
global outpath,simtime
96-
if isinstance(val,str):
97-
time.sleep(2*delay)
98-
elif isinstance(val,list)==False:
99-
print("mywrite must have list or str")
100-
quit()
112+
global simtime
113+
file_path = os.path.join(outpath+str(port), name)
114+
115+
if isinstance(val, str):
116+
time.sleep(2 * delay)
117+
elif not isinstance(val, list):
118+
print("write must have list or str")
119+
return
120+
101121
try:
102-
with open(outpath+str(port)+"/"+name,"w") as outfile:
103-
if isinstance(val,list):
104-
outfile.write(str([simtime+delta]+val))
122+
with open(file_path, "w") as outfile:
123+
if isinstance(val, list):
124+
outfile.write(str([simtime + delta] + val))
105125
simtime += delta
106126
else:
107127
outfile.write(val)
108-
except:
109-
print("skipping"+outpath+str(port)+"/"+name);
128+
except Exception as e:
129+
print(f"Error writing to {file_path}: {e}")
110130

111131
def initval(simtime_val):
112132
global simtime
113-
val = literal_eval(simtime_val)
114-
simtime = val[0]
115-
return val[1:]
133+
try:
134+
val = literal_eval(simtime_val)
135+
simtime = val[0]
136+
return val[1:]
137+
except Exception as e:
138+
print(f"Error parsing simtime_val: {e}")
139+
return []

concoredocker.hpp

Lines changed: 130 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,130 @@
1-
// concoredocker.hpp -- this C++ include file will be the equivalent of concoredocker.py
1+
#ifndef CONCORE_HPP
2+
#define CONCORE_HPP
3+
4+
#include <iostream>
5+
#include <fstream>
6+
#include <sstream>
7+
#include <string>
8+
#include <unordered_map>
9+
#include <vector>
10+
#include <chrono>
11+
#include <thread>
12+
#include <filesystem>
13+
#include <stdexcept>
14+
#include <regex>
15+
16+
class Concore {
17+
public:
18+
std::unordered_map<std::string, std::string> iport;
19+
std::unordered_map<std::string, std::string> oport;
20+
std::string s, olds;
21+
int delay = 1;
22+
int retrycount = 0;
23+
std::string inpath = "/in";
24+
std::string outpath = "/out";
25+
int simtime = 0;
26+
int maxtime = 100;
27+
std::unordered_map<std::string, std::string> params;
28+
29+
Concore() {
30+
iport = safe_literal_eval("concore.iport", {});
31+
oport = safe_literal_eval("concore.oport", {});
32+
default_maxtime(100);
33+
load_params();
34+
}
35+
36+
std::unordered_map<std::string, std::string> safe_literal_eval(const std::string& filename, std::unordered_map<std::string, std::string> defaultValue) {
37+
std::ifstream file(filename);
38+
if (!file) {
39+
std::cerr << "Error reading " << filename << "\n";
40+
return defaultValue;
41+
}
42+
return defaultValue;
43+
}
44+
45+
void load_params() {
46+
std::ifstream file(inpath + "/1/concore.params");
47+
if (!file) return;
48+
std::stringstream buffer;
49+
buffer << file.rdbuf();
50+
std::string sparams = buffer.str();
51+
52+
if (!sparams.empty() && sparams[0] == '"') {
53+
sparams = sparams.substr(1, sparams.find('"') - 1);
54+
}
55+
56+
if (!sparams.empty() && sparams[0] != '{') {
57+
sparams = "{'" + std::regex_replace(std::regex_replace(std::regex_replace(sparams, std::regex(","), ", '"), std::regex("="), "':"), std::regex(" "), "") + "}";
58+
}
59+
}
60+
61+
std::string tryparam(const std::string& n, const std::string& i) {
62+
return params.count(n) ? params[n] : i;
63+
}
64+
65+
void default_maxtime(int defaultValue) {
66+
maxtime = defaultValue;
67+
std::ifstream file(inpath + "/1/concore.maxtime");
68+
if (file) {
69+
file >> maxtime;
70+
}
71+
}
72+
73+
bool unchanged() {
74+
if (olds == s) {
75+
s.clear();
76+
return true;
77+
}
78+
olds = s;
79+
return false;
80+
}
81+
82+
std::vector<std::string> read(int port, const std::string& name, const std::string& initstr) {
83+
std::this_thread::sleep_for(std::chrono::seconds(delay));
84+
std::string file_path = inpath + std::to_string(port) + "/" + name;
85+
std::ifstream infile(file_path);
86+
std::string ins;
87+
88+
if (!infile) {
89+
std::cerr << "File " << file_path << " not found, using default value.\n";
90+
return {initstr};
91+
}
92+
std::getline(infile, ins);
93+
94+
int attempts = 0, max_retries = 5;
95+
while (ins.empty() && attempts < max_retries) {
96+
std::this_thread::sleep_for(std::chrono::seconds(delay));
97+
infile.open(file_path);
98+
if (infile) std::getline(infile, ins);
99+
attempts++;
100+
retrycount++;
101+
}
102+
103+
if (ins.empty()) {
104+
std::cerr << "Max retries reached for " << file_path << ", using default value.\n";
105+
return {initstr};
106+
}
107+
108+
s += ins;
109+
return {ins};
110+
}
111+
112+
void write(int port, const std::string& name, const std::vector<std::string>& val, int delta = 0) {
113+
std::string file_path = outpath + std::to_string(port) + "/" + name;
114+
std::ofstream outfile(file_path);
115+
if (!outfile) {
116+
std::cerr << "Error writing to " << file_path << "\n";
117+
return;
118+
}
119+
if (!val.empty()) {
120+
outfile << "[" << simtime + delta << ", ";
121+
for (size_t i = 0; i < val.size(); ++i) {
122+
outfile << val[i] << (i + 1 < val.size() ? ", " : "");
123+
}
124+
outfile << "]";
125+
simtime += delta;
126+
}
127+
}
128+
};
129+
130+
#endif

0 commit comments

Comments
 (0)