可能以一种或另一种方式上最常见的答案是:
awk -F',' 'NR==FNR{ids[$1]; next} $1 in ids' ids.csv data.csv > out.csv
这将比您现有的脚本快。
关于为什么您的原始脚本很慢,请参见 Why-is-Is-us-a-shell-shell-loop-to-to-tox-text-text-text-the-tossed-bad-practice 。
根据我的理解,您想显示表单实例的值。您可以做:
form.instance.parent.name
您似乎正在混淆一些问题。
为什么Akka有自己的RPC而不是HTTP。
答案是路由/可靠性。 Akka的目的是分布式分布式系统,当您进行RAW HTTP时,如何使所有消息保持正确的所有路线?另外,使用大量机器,您如何确保每次通话一次一次,仅在群集上一次发生一次?
为什么要与演员打扰?
演员是高度并发系统的模式。演员允许开发人员推理状态寿命和流程居住的地方,将它们分开,并允许演员运行时快速运行大量演员实例,而不必担心复杂的事物,例如“线程”和“线程安全”。
当您到达职业生涯的某个点时,您会发现“线程安全”非常难以正确。哎呀,我最喜欢的编程语言是一种以迫使您正确进行线程而闻名的语言。问题在于,如果没有一些系统的过程来编写代码,那么在完全不同的项目中,两个看似无关的代码行可能会产生难以复制的细微错误。
高度并发系统的另一个范式是功能性编程,但是与其相关的绩效惩罚。
TLDR
Actors模式旨在解决您在大型庞大的代码库中遇到的问题,许多非天然级别的开发人员同时使用数百台服务器运行。
您问题的核心是:
结果对于小表来说是正确的,但是1000万行只会导致记忆错误,我正在寻找避免这种情况的方法。
遵循您的顶级问题语句,但使用较少通用的结构,我们可以做类似的事情:
def runQuery(dataLines):
from collections import defaultdict
pred = dict(zip(['follows','friendOf','likes','hasReview'],range(4)))
tables = [defaultdict(list) for _ in pred]
def encode(s):
if s[-1].isdigit():
i = 0
while s[-1 - i].isdigit():
i += 1
return int(s[-i:])
if any(s.endswith(k) for k in pred):
return sum(v for k, v in pred.items() if s.endswith(k))
return None
for line in dataLines:
if not line:
continue
subj, prop, *obj = line.rstrip('\n.').split('\t')
obj = obj[0].rstrip()
subj, prop, obj = [encode(s) for s in (subj, prop, obj)]
if prop is not None:
tables[prop][subj].append(obj)
tables = [{k:tuple(v) for k, v in table.items()} for table in tables]
#[print(list(pred.keys())[i], tables[i], sep='\n') for i in range(len(pred))]
# create reverse index for subject, object where subject [user] follows object [user]
object_of_follows = defaultdict(set)
for k, v in tables[pred['follows']].items():
for user in v:
object_of_follows[user].add(k)
# create reverse index for subject, object where subject [user] is friendOf object [user]
object_of_friendOf = defaultdict(set)
for k, v in tables[pred['friendOf']].items():
if k in object_of_follows:
for user in v:
object_of_friendOf[user].add(k)
# create reverse index for subject, object where subject [user] likes object [product]
object_of_likes = defaultdict(set)
for k, v in tables[pred['likes']].items():
if k in object_of_friendOf:
for product in v:
object_of_likes[product].add(k)
# create reverse index for subject, object where subject [product] hasReview object [review]
object_of_hasReview = defaultdict(set)
for k, v in tables[pred['hasReview']].items():
if k in object_of_likes:
for review in v:
object_of_hasReview[review].add(k)
def addToResult(result, e):
d = object_of_hasReview[e]
c = {y for x in d for y in object_of_likes[x]}
b = {y for x in c for y in object_of_friendOf[x]}
a = {y for x in b for y in object_of_follows[x]}
toAdd = [(ax, bx, cx, dx, e) for dx in d for cx in c for bx in b for ax in a]
result += toAdd
result = []
for e in object_of_hasReview:
addToResult(result, e)
print(f'result row count {len(result):,}')
return result
说明:
- 创建4个表的列表(
conters,friendf,likes,likes,hasreview
),每个词典映射受对象元组的约束, - 创建4个反向索引(
object_of_follows,object_of_friendof,object_of_likes, object_of_hasreview
);例如:-
object_of_follows
是一个dict,它映射每个用户中的对象都遵循
映射到一组用户,每个用户都是中的主题,请的代码>
)
在friendf
atobject_of_follows
(换句话说,是中一个或多个主题的对象,
conters - 等。
- 中
object_of_hasreview
中包含每个唯一结果的多个结果行
contrys.subject,closts.Object,object,friendsof.object,likes.object, hasreview.Object
,如查询中指定的 - 返回所有此类爆炸行的列表。
1000万行的测试代码:
dataLines = []
numFollowers = 1000
numChildren = 10
overlapFactor = max(1, numChildren // 2)
def largerPowerOfTen(x):
y = 1
while x >= y:
y *= 10
return y
aCeil = largerPowerOfTen(numFollowers)
bCeil = largerPowerOfTen(aCeil * numChildren)
cCeil = largerPowerOfTen(bCeil * numChildren)
dCeil = largerPowerOfTen(cCeil * numChildren)
friendOf, likes = set(), set()
for a in range(numFollowers):
for b in range(aCeil + a * overlapFactor, aCeil + a * overlapFactor + numChildren):
dataLines.append(f'wsdbm:User{a} wsdbm:follows wsdbm:User{b} .\n')
for c in range(bCeil + b * overlapFactor, bCeil + b * overlapFactor + numChildren):
if (b,c) not in friendOf:
dataLines.append(f'wsdbm:User{b} wsdbm:friendOf wsdbm:User{c} .\n')
friendOf.add((b,c))
for d in range(cCeil + c * overlapFactor, cCeil + c * overlapFactor + numChildren):
if (c,d) not in likes:
dataLines.append(f'wsdbm:User{c} wsdbm:likes wsdbm:Product{d} .\n')
likes.add((c,d))
for e in range(dCeil * (d + 1), dCeil * (d + 1) + numChildren):
dataLines.append(f'wsdbm:Product{d} wsdbm:hasReview wsdbm:Review{e} .\n')
print(f'dataLines row count {len(dataLines):,}')
from timeit import timeit
n = 1
print(f'Timeit results:')
t = timeit(f"runQuery(dataLines)", setup=f"from __main__ import dataLines, runQuery", number=n) / n
print(f'======== runQuery ran in {t} seconds using {n} iterations')
'''
result = runQuery(dataLines)
print(f'result row count {len(result):,}')
print(f'{"follows.subject":>20}{"follows.object":>20}{"friendsOf.object":>20}{"likes.object":>20}{"hasReview.object":>20}')
[print(f'{a:20}{b:20}{c:20}{d:20}{e:20}') for a,b,c,d,e in result]
'''
输出:
dataLines row count 10,310,350
Timeit results:
result row count 12,398,500
======== runQuery ran in 81.53253880003467 seconds using 1 iterations
较小规模的样本运行中的输入/输出:
参数
numFollowers = 3
numChildren = 3
overlapFactor = 2
输入(存储在表中):
follows
{0: (10, 11, 12), 1: (12, 13, 14), 2: (14, 15, 16)}
friendOf
{10: (120, 121, 122), 11: (122, 123, 124), 12: (124, 125, 126), 13: (126, 127, 128), 14: (128, 129, 130), 15: (130, 131, 132), 16: (132, 133, 134)}
likes
{120: (1240, 1241, 1242), 121: (1242, 1243, 1244), 122: (1244, 1245, 1246), 123: (1246, 1247, 1248), 124: (1248, 1249, 1250), 125: (1250, 1251, 1252), 126: (1252, 1253, 1254), 127: (1254, 1255, 1256), 128: (1256, 1257, 1258), 129: (1258, 1259, 1260), 130: (1260, 1261, 1262), 131: (1262, 1263, 1264), 132: (1264, 1265, 1266), 133: (1266, 1267, 1268), 134: (1268, 1269, 1270)}
hasReview
{1240: (12410000, 12410001, 12410002), 1241: (12420000, 12420001, 12420002), 1242: (12430000, 12430001, 12430002, 12430000, 12430001, 12430002), 1243: (12440000, 12440001, 12440002), 1244: (12450000, 12450001, 12450002, 12450000, 12450001, 12450002, 12450000, 12450001, 12450002), 1245: (12460000, 12460001, 12460002, 12460000, 12460001, 12460002), 1246: (12470000, 12470001, 12470002, 12470000, 12470001, 12470002, 12470000, 12470001, 12470002), 1247: (12480000, 12480001, 12480002), 1248: (12490000, 12490001, 12490002, 12490000, 12490001, 12490002, 12490000, 12490001, 12490002, 12490000, 12490001, 12490002), 1249: (12500000, 12500001, 12500002, 12500000, 12500001, 12500002, 12500000, 12500001, 12500002), 1250: (12510000, 12510001, 12510002, 12510000, 12510001, 12510002, 12510000, 12510001, 12510002, 12510000, 12510001, 12510002, 12510000, 12510001, 12510002), 1251: (12520000, 12520001, 12520002, 12520000, 12520001, 12520002), 1252: (12530000, 12530001, 12530002, 12530000, 12530001, 12530002, 12530000, 12530001, 12530002, 12530000, 12530001, 12530002, 12530000, 12530001, 12530002), 1253: (12540000, 12540001, 12540002, 12540000, 12540001, 12540002, 12540000, 12540001, 12540002), 1254: (12550000, 12550001, 12550002, 12550000, 12550001, 12550002, 12550000, 12550001, 12550002, 12550000, 12550001, 12550002), 1255: (12560000, 12560001, 12560002), 1256: (12570000, 12570001, 12570002, 12570000, 12570001, 12570002, 12570000, 12570001, 12570002, 12570000, 12570001, 12570002), 1257: (12580000, 12580001, 12580002, 12580000, 12580001, 12580002, 12580000, 12580001, 12580002), 1258: (12590000, 12590001, 12590002, 12590000, 12590001, 12590002, 12590000, 12590001, 12590002, 12590000, 12590001, 12590002, 12590000, 12590001, 12590002), 1259: (12600000, 12600001, 12600002, 12600000, 12600001, 12600002), 1260: (12610000, 12610001, 12610002, 12610000, 12610001, 12610002, 12610000, 12610001, 12610002, 12610000, 12610001, 12610002, 12610000, 12610001, 12610002), 1261: (12620000, 12620001, 12620002, 12620000, 12620001, 12620002, 12620000, 12620001, 12620002), 1262: (12630000, 12630001, 12630002, 12630000, 12630001, 12630002, 12630000, 12630001, 12630002, 12630000, 12630001, 12630002), 1263: (12640000, 12640001, 12640002), 1264: (12650000, 12650001, 12650002, 12650000, 12650001, 12650002, 12650000, 12650001, 12650002), 1265: (12660000, 12660001, 12660002, 12660000, 12660001, 12660002), 1266: (12670000, 12670001, 12670002, 12670000, 12670001, 12670002, 12670000, 12670001, 12670002), 1267: (12680000, 12680001, 12680002), 1268: (12690000, 12690001, 12690002, 12690000, 12690001, 12690002), 1269: (12700000, 12700001, 12700002), 1270: (12710000, 12710001, 12710002)}
输出
result row count 351
follows.subject follows.object friendsOf.object likes.object hasReview.object
0 10 120 1240 12410000
0 10 120 1240 12410001
0 10 120 1240 12410002
0 10 120 1241 12420000
0 10 120 1241 12420001
0 10 120 1241 12420002
0 10 120 1242 12430000
0 10 121 1242 12430000
0 10 120 1242 12430001
0 10 121 1242 12430001
0 10 120 1242 12430002
0 10 121 1242 12430002
0 10 121 1243 12440000
0 10 121 1243 12440001
0 10 121 1243 12440002
0 10 121 1244 12450000
0 11 121 1244 12450000
0 10 122 1244 12450000
0 11 122 1244 12450000
0 10 121 1244 12450001
0 11 121 1244 12450001
0 10 122 1244 12450001
0 11 122 1244 12450001
0 10 121 1244 12450002
0 11 121 1244 12450002
etc.
您可以做类似的事情:
$("label:contains('STATIC TEXT I CAN FIND')").closest('div').parent().next().find('ul').next().html()
或
$("div > div > div > ul > li:eq(1) > div > div").html();
按钮默认为 type =“ commitd”
内部表单中,如果您想要一个不触发提交的普通按钮,最简单的解决方案是明确设置prop type =“ button” 上。
此“闪烁错误”只是帖子后的页面重新加载
我认为您的实际代码可能存在几个问题。
首先,由于您使用表单登录的事实,请在定义过滤器链时尝试提供适当的配置,例如:
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.cors().disable()
.authorizeHttpRequests()
.antMatchers("/", "/login", "/logout", "/register", "/error", "/css/**", "/js/**", "/img/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
// Note the inclusion of the login processing url value
.loginProcessingUrl("/authenticate")
// One that you consider appropriate
.defaultSuccessUrl("/home")
.failureUrl("/login?error=true")
.and().authenticationProvider(authProvider());
return http.build();
}
如您所见,我们指出的是,您的控制器/都将处理登录页面登录
映射:
@RequestMapping(value = "/login")
public String login(Model model) {
return "login";
}
此外,我们指示/authenticate
是登录处理URL配置:这将激活您和Spring Security提供的所有身份验证内容,以验证用户的身份验证。
请注意,您还需要更改 login.html
页面,因为在当前实现中,用户名/密码表格也正在针对/login
- 这可能是您在更新2中描述的问题的原因。在示例之后,该表单应针对/Authenticate
:
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login</title>
<linl rel="stylesheet" th:href="@{/css/style.css}"></linl>
</head>
<body>
<form method="post" th:action="@{/authenticate}">
<input type="text" name="username" placeholder="Usuário">
<input type="password" name="password" placeholder="Senha">
<input type="submit" value="Entrar">
</form>
<script th:src="@{/js/script.js}"></script>
</body>
</html>
请注意,我们还包括一条路由,/home
在成功的身份验证后请求您的应用程序。 yu可以在 app
中定义类似:
@RequestMapping(value = "/home")
public String home(Model model) {
return "home";
}
和简单的HTML测试页面, home.html
:
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" th:href="@{/css/style.css}">
</head>
<body>
Authenticated!!
<script th:src="@{/js/script.js}"></script>
</body>
</html>
为了进行此工作,您应该在软件中更改一份其他部分。根据您定义代码的方式,当Spring Security尝试阅读您的 usuario
GrantedAuthorities
Hibernate将发布众所周知的未能懒惰地初始化角色集合。 。,因为在当前实施中,您正在阅读数据库中存储的凭据,但没有会话:
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
List<Autorizacao> lista = new ArrayList<Autorizacao>();
for(Credencial credencial : credenciais) {
lista.addAll(credencial.getAutorizacoes());
}
return lista;
}
您可以以不同的方式解决问题,尤其是考虑使用@transactional
,而是一个直截了当的解决方案可能是引起的。
首先,修改您的 usuario
对象,并包含一个瞬态属性,用于存储授予弹簧安全的凭据:
package org.kleber.app.model.usuario;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Transient;
import org.kleber.app.model.credencial.Credencial;
import org.kleber.app.model.Model;
import org.kleber.app.model.autorizacao.Autorizacao;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
@Entity
public class Usuario extends Model implements UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Integer id;
@Column
String username;
@Column
String password;
@Column
String firstName;
@Column
String lastName;
@Column
String email;
@ManyToMany
List<Credencial> credenciais;
@Transient
Collection<? extends GrantedAuthority> authorities = Collections.emptySet();
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public List<Credencial> getCredenciais() {
return credenciais;
}
public void setCredenciais(List<Credencial> credenciais) {
this.credenciais = credenciais;
}
public boolean isEnabled() {
return true;
}
public boolean isCredentialsNonExpired() {
return true;
}
public boolean isAccountNonExpired() {
return true;
}
public boolean isAccountNonLocked() {
return true;
}
public void setAuthorities(Collection<? extends GrantedAuthority> authorities) {
this.authorities = authorities;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
}
下一步,在 usuariodao
中包含一个自定义方法主动 session
:
package org.kleber.app.model.usuario;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import org.kleber.app.model.Dao;
import org.kleber.app.model.autorizacao.Autorizacao;
import org.kleber.app.model.credencial.Credencial;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
@Repository
public class UsuarioDao extends Dao<Usuario> {
UsuarioDao() {
super(Usuario.class);
}
public Usuario findByUsername(String username) {
EntityManager entityManager = getEntityManager();
entityManager.getTransaction().begin();
Usuario usuario = (Usuario) entityManager.createQuery("SELECT a FROM Usuario a WHERE a.username = :value").setParameter("value", username).getSingleResult();
// Retrieve the credentials here
// On the contrary, you will face: failed to lazily initialize a collection of role...
// Please consider using @Transactional instead
List<Credencial> credenciais = usuario.getCredenciais();
List<Autorizacao> autorizacaos = new ArrayList<Autorizacao>();
for(Credencial credencial : credenciais) {
autorizacaos.addAll(credencial.getAutorizacoes());
}
usuario.setAuthorities(autorizacaos);
entityManager.getTransaction().commit();
entityManager.close();
return usuario;
}
}
,如我提到的那样,请考虑使用@transactional
和Spring内置的交易分界机制,而不是以这种方式独自处理交易。
最后,在您的 userDetailsService
实现中用户用户此新方法:
@Bean
public UserDetailsService userDetailsService() {
return new UserDetailsService() {
@Override
public UserDetails loadUserByUsername(String username) {
System.out.println("loadUserByUsername: " + username);
return usuarioDao.findByUsername(username);
}
};
}
而不是在 usuariodao
中创建此新方法,也许更好的是,可能性是创建 uservice
> @service
包装此 usuario
和凭据
初始化过程:此服务将被您的 userDetailsService
实现。
为了完整性,这就是 app
类的结局,
package org.kleber.app;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.annotation.Bean;
import org.thymeleaf.extras.springsecurity5.dialect.SpringSecurityDialect;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import java.security.MessageDigest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.ui.Model;
import java.util.ArrayList;
import org.springframework.beans.factory.annotation.Autowired;
import org.kleber.app.model.usuario.UsuarioDao;
import org.kleber.app.model.credencial.CredencialDao;
import org.kleber.app.model.usuario.Usuario;
import org.kleber.app.model.credencial.Credencial;
@SpringBootApplication
@Controller
public class App extends SpringBootServletInitializer {
@Autowired
UsuarioDao usuarioDao;
@Autowired
CredencialDao credencialDao;
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(App.class);
}
@Bean
public SpringSecurityDialect springSecurityDialect() {
return new SpringSecurityDialect();
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.cors().disable()
.authorizeHttpRequests()
.antMatchers("/", "/login", "/logout", "/register", "/error", "/css/**", "/js/**", "/img/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/authenticate")
.defaultSuccessUrl("/home")
.failureUrl("/login?error=true")
.and().authenticationProvider(authProvider());
return http.build();
}
@Bean
public DaoAuthenticationProvider authProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setPasswordEncoder(passwordEncoder());
provider.setUserDetailsService(userDetailsService());
return provider;
}
@Bean
public UserDetailsService userDetailsService() {
return new UserDetailsService() {
@Override
public UserDetails loadUserByUsername(String username) {
System.out.println("loadUserByUsername: " + username);
return usuarioDao.findByUsername(username);
}
};
}
@Bean
public PasswordEncoder passwordEncoder() {
return new PasswordEncoder() {
@Override
public String encode(CharSequence rawPassword) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(rawPassword.toString().getBytes());
byte[] digest = md.digest();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < digest.length; i++)
sb.append(Integer.toString((digest[i] & 0xff) + 0x100, 16).substring(1));
return sb.toString();
} catch (Exception e) {
return null;
}
}
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
return encodedPassword.equals(encode(rawPassword));
}
};
}
@RequestMapping(value = "/")
public String index(Model model) {
return "index";
}
@RequestMapping(value = "/home")
public String home(Model model) {
return "home";
}
@RequestMapping(value = "/login")
public String login(Model model) {
return "login";
}
@RequestMapping(value = "/register", method = RequestMethod.GET)
public String register(Model model) {
model.addAttribute("obj", new Usuario());
return "register";
}
@RequestMapping(value = "/register", method = RequestMethod.POST)
public String register(@ModelAttribute Usuario usuario) {
try {
usuario.setPassword(passwordEncoder().encode(usuario.getPassword()));
usuario.setCredenciais(new ArrayList<Credencial>());
usuario.getCredenciais().add(credencialDao.findBy("nome", "USER").get(0));
usuarioDao.insert(usuario);
return "login";
} catch (Exception e) {
e.printStackTrace();
return "register";
}
}
}
可能会以不同的方式进行改进,但是建议的设置应允许您成功访问应用程序:
Spring具有 @scheduled
注释。有几种配置它的方法,一种方法是像Unix Cron作业一样配置它。
例如:
@Scheduled(cron = "0 15 10 15 * ?")
public void scheduleTaskUsingCronExpression() {
long now = System.currentTimeMillis() / 1000;
System.out.println(
"schedule tasks using cron jobs - " + now);
}
此处的任务计划在每个月的15天在上午10:15执行。
但是,也有一种方法可以在运行时动态配置延迟或速率,例如这样(取自baeldung.com):
@Configuration
@EnableScheduling
public class DynamicSchedulingConfig implements SchedulingConfigurer {
@Autowired
private TickService tickService;
@Bean
public Executor taskExecutor() {
return Executors.newSingleThreadScheduledExecutor();
}
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(taskExecutor());
taskRegistrar.addTriggerTask(
new Runnable() {
@Override
public void run() {
tickService.tick();
}
},
new Trigger() {
@Override
public Date nextExecutionTime(TriggerContext context) {
Optional<Date> lastCompletionTime =
Optional.ofNullable(context.lastCompletionTime());
Instant nextExecutionTime =
lastCompletionTime.orElseGet(Date::new).toInstant()
.plusMillis(tickService.getDelay());
return Date.from(nextExecutionTime);
}
}
);
}
}
行即时NextExecution Time = ...
可以用自己的逻辑代替设置下一个执行时间,就像从数组中解析时间一样。
看一下有关它的贝尔登教程: https://wwww.baeldung-com/spring-spring-scheduled -tasks
也请在这里查看cron符号: https://www.netiq.com/documentation/cloud-manager-2-5/ncm-reference/data/bexyssf.html
注意:这个答案已经过时了。它适用于Python 2使用 new
模块,该模块在2008年进行了弃用。
有python内置功能setattr和getAttr。可以用来设置和获取类的属性。
一个简短的例子:
>>> from new import classobj
>>> obj = classobj('Test', (object,), {'attr1': int, 'attr2': int}) # Just created a class
>>> setattr(obj, 'attr1', 10)
>>> setattr(obj, 'attr2', 20)
>>> getattr(obj, 'attr1')
10
>>> getattr(obj, 'attr2')
20
我看不到您正在初始化目录,如此 post :
const bucket = gcs.bucket(object.bucket);
const filePath = object.name;
const fileName = filePath.split('/').pop();
const thumbFileName = 'thumb_' + fileName;
const workingDir = join(tmpdir(), `${object.name.split('/')[0]}/`);//new
const tmpFilePath = join(workingDir, fileName);
const tmpThumbPath = join(workingDir, thumbFileName);
await fs.ensureDir(workingDir);
另外,请考虑,如果您使用两个函数,则不会共享/tmp
目录,因为每个功能都有自己的。这是 Dogn> DOUG Stevenson 。在相同的答案中,有一个很好的解释视频,有关本地和全球范围以及如何使用TMP目录:
云功能仅允许一个功能一次在特定服务器实例中运行。在具有不同 /TMP空间的不同服务器实例上并行运行的功能。每个函数调用彼此完全隔离。您应该始终清理您在 /tmp中编写的文件,以免它们积累并导致服务器实例随着时间的推移而用完。< /p>
我建议使用 Google Cloud Storage扩展了云功能以实现您目标。
如此其他答案:
这就是 nick-wnick 在他的评论。
这是另一个答案更好地解释了每个选项的用例:
set
没有MERGE
将覆盖文档或创建它,如果它不存在set
带有MERGE
将在文档中更新字段,或者如果不存在,则创建它更新
将更新字段,但是如果文档不存在,将失败创建
将创建文档,但是如果文档已经存在,则会失败
您可以按照以下示例显示的数字字段值递增或降低数字字段值。增量操作增加或降低了字段的当前值。
//原子上将城市人口增加50。 washingtonref.update({ 人口:firebase.firestore.fieldvalue.Increment(50) });
另请参见:
- 用云firestore 在原子上递增值
这是因为令牌缺少填充物。尝试一下
This is because the token is missing the padding. Try this
用ATOB在前端解码JWT令牌使我无法执行ATOB&#x27;在窗口上&#x27;错误